# Real-Word probes, 2026-10-24

Observations behind the word-valid policy for #388, #392, #396, #397, #351, #398, #402, #408, #409, #410 and #411, the scope of `word-content-type-invalid` (#401), the defects session 3 found (#380, #414, #431–#437), what sessions 4–6 settled for #380, #408, #409, #411, #414, #433, #437 and #443, what session 7 settled for #414, #450 and #451, what sessions 8–13 settled for #408, #432, #437, #443, #451, #453 and #458, what session 14 settled for #459 and #464, what session 15 settled for review AM's findings on #437 and #432 (#514, #515, #516, #517), what session 16 settled for review AR's suspected items on #516 and #517 and its finding F1 (#535, #539, #540), what session 17 settled for the glossary's reach and for exact content types (#549, #550), what session 18 settled for review AS's question on NFC/NFD-distinct names (#441), what session 19 settled for the glossary's own styles, settings, fontTable, webSettings and numbering parts (#562), and what session 20 settled for the glossary's remaining relationships, a MIME parameter on the remaining Word-read parts and the generic Default on numbering and theme (#549, #569, #570, #571), and what sessions 21 and 22 settled for padded and unused-part content types, the content types of a glossary's own parts, an empty main-document content type and the items adversarial review AU suspected (#570, #579, #581), what session 23 settled for the items adversarial review AW suspected (#595, #596), what session 24 settled for the items adversarial review AX suspected (#595, #600, #601), what session 25 settled for the default-profile drift the Validator Diff Report flagged on #322 (#271), what session 26 settled for the items adversarial review AY suspected (#606, #607, #610), what session 27 settled for the relationship types and placements adversarial review AZ left open (#613), what session 28 settled for a hyperlink's relationship type (#614), what session 29 settled for duplicate relationship Ids and `https:` relationship Types (#615, adversarial review BA), what session 30 settled for duplicate relationship Ids outside the package and main-document `.rels` (#617, adversarial review BB), what session 31 settled for duplicate relationship Ids beside a story root stored without a `.xml` suffix (#618, adversarial review BC), what session 32 settled for a story reference whose `r:id` names no relationship and for a main document stored without a `.xml` suffix (#619, #620, adversarial review BD), and what session 33 settled for story references with an empty, missing or ISO Strict `r:id`, story roots stored as `word/header1.xml`, and markup compatibility in relationships parts (#623, #624, #625, #631, #632, adversarial reviews BE and BG), what session 34 settled for parts reached only through a relationship markup compatibility selects and for markup-compatibility errors in relationships parts (#634, #635, #636, the adversarial review of #632's fix), and what session 35 settled for the adversarial review of layer 130: relationship ids `rels-missing-sidecar` counts that Word never resolves (#638), and story-reference ids outside the body `w:sectPr`; and what session 36 settled for the adversarial reviews of #636 and layer 131: which relationships parts' markup-compatibility errors Word rejects (#644), a chart no drawing references (#645), and a root-wrapped package relationships part (#640, #646); and what session 37 settled for #644's remaining sidecars and #645's boundary shapes (#647); and the package relationships root wrappers #646's fix accepts (session 38); and the chart sources and package-root wrapper combinations layer 133's review found accepted without evidence (#661, #662, session 39); and the paragraph-id repair's output and the External relationship targets #653's and #665's fixes change (session 40); and the Word outcomes of the 56 package fixtures layer 136 pins, each observed in two separate runs and read from both runs' logs (session 41); and Word's verdicts on the stored item names the package view refuses and `opc-item-name-refused` reports (#629, session 42), and the dialog for the empty segment session 42 left `unknown` (#629, session 43), and which relationship types make Word load a part whose own relationships part is missing (#647, session 44).

- Word: Microsoft Word for Mac 16.115 (build 16.115.26100424), platform `darwin`.
- Transport, sessions 1 and 2: `verifyInWord` (`src/lib/word-verifier.ts`). It opens each specimen by path, reads Word's window and dialog state, and never saves.
- Transport, session 3: `neurotic_docx_bench/scripts/word_pdf.py` in its default batch mode (`--label wfv --no-check-preset`). It stages each file inside Word's container as `NNNNN__wfv__<file>`, opens it, and exports a PDF when Word reads it. When Word shows an alert, it brings Word forward, answers a repair prompt No and then the OK that follows, and logs the alert's words. A file's outcome comes only from an alert that names its staged file, never from timing (`wordpdf_outcomes.py`, reproduced at the end). The specimens' SHA-256 were checked against the files handed to the driver after each run, and no specimen was rebuilt between build and run.
- Transport, sessions 4–13: the same driver in the same mode, run in the foreground, as its documentation requires. Single-specimen runs are attributed by the same parser. The runner and the helper that copies one specimen into its own run are reproduced at the end.
- Outcomes: `clean-open` means Word opened the document with no dialog. `repair-warning` means Word showed "Word found unreadable content … Do you want to recover the contents of this document?". `open-error` means Word showed "Word experienced an error trying to open the file." In session 3, `inconclusive` means Word loaded no document in two passes and no alert named the file. Word stayed alive throughout, and `~/Library/Logs/DiagnosticReports` holds no Word report from any session. In session 3 the driver itself restarted Word after runs of empty loads, as designed.
- Specimens: built in code from `MINIMAL_PARTS` (`tests/support/minimal-docx.ts`). The `398-dup-theme-*` specimens are built from `tests/fixtures/broken/package.word-duplicate-theme.docx`, which was only read. The probe script that builds, validates and opens them is reproduced at the end of this file. No fixture or manifest was changed.
- Validator: the `word-valid` and `strict` columns record `validate()` **at probe time**, before the policy changes the probes motivated. They are not current verdicts. Session 1 (02:18Z–02:26Z) ran against `wfv/46-plan-audit` (199c2d5b); session 2 (03:10Z–03:19Z) ran against `wfv/51-directory-staging` (ad072db8). Session 3's columns are `validate()` at `wfv/57-central-directory-names` (ab7f311d), run on the exact files Word was given. The columns for sessions 4–6 are `validate()` at `wfv/62-ct-duplicate-declaration` (3126dcfc). They were recomputed after the sessions on the exact files Word was given, and every SHA-256 was checked against its record. Session 7's columns are `validate()` at `wfv/65-override-partname` before (9960b273) and after (34d0ace3) the #450 fix, recomputed the same way; the verdicts recorded at build time equal the 9960b273 ones. Sessions 8–13's columns are `validate()` at 49922e9a, the commit the specimens were built against, and at `wfv/66-partname-review-fixes` (e08611b1) after the #453 and #458 fixes, recomputed the same way with every SHA-256 checked; the verdicts recorded at build time equal the 49922e9a ones. Session 14's columns are `validate()` at ed34e3bf. Session 15's columns are `validate()` at `wfv/87-zip64-rekey` (8252ce4f), the commit the specimens were built against, recorded at build time on the exact files Word was given; every SHA-256 was re-checked against its record after the runs. Session 16's columns are `validate()` at `wfv/98-iri` (98902c85), recorded the same way. Session 17's columns are `validate()` at `wfv/100-word-probes-s16` (3ebe3e7f, whose source is layer 99's), session 18's at `wfv/101-glossary-header` (ab1fba79), session 19's at `wfv/108-segment-doc` (4c86cbfe), session 20's at `wfv/113-glossary-eager` (52fdbd8b), and sessions 21 and 22's at `wfv/115-word-probes-s20` (cb36e27a), recorded the same way.

## What the observations decide

- **#388: package relationships.** A zero-byte, truncated or undeclared-prefix `_rels/.rels` makes Word offer recovery, and the readable control opens clean. Word-valid passed all three, so `xml-syntax` and `xml-undeclared-prefix` on `_rels/.rels` are now Word-blocking.
- **#392: `WORD/` folder.** A package with every Word part under `WORD/` opens clean. With its main part malformed, Word refuses it exactly as it refuses the lower-case control. That matches the current policy, which matches `word/` by OPC part name.
- **#396: content-types stream spelling.** A stream stored as `[CONTENT_TYPES].XML` opens clean. Malformed, it makes Word offer recovery, as word-valid predicts. That matches the any-case lookup.
- **#397: unknown declared encoding.** `word/document.xml` declaring `X-UNKNOWN-ENCODING` makes Word refuse the file, and the `windows-1252` control opens clean. Word-valid passed it, so this was a false negative; `xml-encoding` now follows the `xml-syntax` path policy. Session 2 confirms the inferred scope:
    - the same declaration in `word/styles.xml`, in the content-types stream and in `_rels/.rels` makes Word offer recovery;
    - a `word/document.xml` declared UTF-8 holding a lone Latin-1 byte makes Word refuse it;
    - word-valid fails all four;
    - in `docProps/core.xml` the declaration also makes Word offer recovery, but word-valid passes it (#409).
- **#351: equivalent part names.** Every duplicate probed makes Word offer recovery, even when both spellings hold identical bytes: case variants, an unreserved escape (`word/%73tyles.xml`), a backslash (`word\document.xml`), and two content-types streams. Word-valid passed the escape and backslash duplicates. A single backslash name is read as `/`: the main part stored only as `word\document.xml` opens clean (#374).
- **#408: escaped item names (OPC [M1.8]).** Any stored name with a percent-escaped unreserved character makes Word offer recovery:
    - the styles part stored only as `word/%73tyles.xml`;
    - the main part stored only as `word/%64ocument.xml`;
    - the sidecar stored as `document.xml.%72els`;
    - an unreferenced extra `word/%78tra.xml`, which settles the cause, since nothing points at it;
    - the styles control (its part missing, its relationship kept) opens clean, so a missing target is not the cause;
    - word-valid passed the first two and the extra item.
- **#398 and #402: `.RELS` sidecar.** A `.RELS`-spelled document sidecar opens clean. With two theme relationships, Word offers recovery for both the `.rels` control and the `.RELS` variant, as word-valid now predicts for both. An external hyperlink resolved through a `.RELS` sidecar opens clean, as the `.rels` control does, but word-valid fails it. That is the #402 false positive: the sidecar lookups must fold case. Through a `.%72els` sidecar, Word offers recovery; that is #408.
- **#409: core properties.** A truncated `docProps/core.xml`, or one declaring an unknown encoding, makes Word offer recovery. Word-valid passes both, because docProps findings are downgraded. The `docProps/app.xml` control opens clean. Session 3 settles the rule (below).
- **#401: `word-content-type-invalid`.** An `invalid-*` type on an existing part makes Word refuse the file or offer recovery: styles, the main part and core properties. The same type on an `Override` for a missing part, or on a `Default` that covers no part, opens clean. The check over-reported; it now reports only declarations that apply to a stored part.

Session 3 adds:

- **#409: properties parts are read through their relationships.** Truncated, undeclared-prefix and unknown-encoding `docProps/core.xml`, `app.xml` and `custom.xml`, each named by its package relationship, make Word offer recovery. The same defects in unreferenced `core.xml`, `app.xml` and `custom.xml` open clean. A truncated core part stored as `props/meta.xml` and named by the core-properties relationship makes Word offer recovery, and its well-formed control opens clean. So Word reads what the relationship names, wherever it is stored. Word-valid passes every one of these (lane 409 implements the rule).
- **#410: real encodings libxml2 cannot decode.** `word/document.xml` declaring `macintosh`, `x-mac-cyrillic`, `IBM866` or `UTF-7` makes Word refuse the file. The `windows-1252` control with non-ASCII text opens clean. Word-valid already fails all four, so the policy stands; the README now says it covers these labels.
- **#411: identical stored names and dot segments.** Two entries stored under the identical name `word/document.xml` make Word offer recovery, whichever entry is malformed, and so do two `..` item names. At ab7f311d word-valid fails all five.
- **#408: every unreserved escape probed.** `%41` (upper-case letter), `%30` (digit), `%2D` and `%2d` (hyphen), `%2E`, `%5F` and `%7E` in an unreferenced extra item all make Word offer recovery. The `%20` control (a reserved character) opens clean. An extra `[Content_Types].%78ml` item beside the real stream makes Word offer recovery too, so the check is right to report a stream spelling (review X F1).
- **#436: escaped `/` and `\` (OPC [M1.7]).** An unreferenced `word%2Fxtra.xml` makes Word offer recovery, and `word%5Cxtra.xml` makes it refuse the file. Word-valid passes both.
- **#414: `Override` PartNames that are not part names.** The session 3b styles specimens are confounded (#432, below). Session 3c adds an `Override` with `ContentType="invalid-x"` for a part that does not exist. With the plain `PartName` `/word/nothere.xml`, it opens clean. With `..`, `#fragment` or a backslash, Word offers recovery, and with `?query` it refuses the file. Word-valid passes all four.
- **#432: a styles part typed by the generic Default.** Removing the styles `Override`, so that `word/styles.xml` falls to `<Default Extension="xml" ContentType="application/xml"/>`, makes Word offer recovery. Nothing reports it.
- **#431: duplicate content-type declarations.** Two `Default`s for one extension (identical, or differing in case) and two `Override`s for one part (identical, conflicting, or differing in case) all make Word offer recovery. Word-valid and strict pass all five.
- **#433 and #434: package relationships structure.** A foreign element anywhere in `_rels/.rels`, whether beside the relationships or wrapping the main one, makes Word offer recovery, and so does a root other than `Relationships`. Word-valid passes all three; strict fails them through the XSD walk only.
- **#435: no content-types stream.** Without `[Content_Types].xml`, Word offers recovery. Word-valid reports `ct-missing` as a warning only.
- **#380: no main part.** An empty ZIP and a package without `word/document.xml` make Word offer recovery. Word-valid passes both. A package whose main relationship is removed is inconclusive.
- **#437: an unreferenced malformed part under `word/`.** A truncated, unreferenced `word/xtra.xml` opens clean, but word-valid fails it. This is a false positive of the `word/` folder rule; reachability, as for the properties parts, would fit both observations.

Sessions 4–6 add:

- **#380: a removed main relationship.** With the `officeDocument` relationship removed and `word/document.xml` kept, Word offers recovery. All three #380 shapes are therefore Word-blocking. Word-valid at 3126dcfc passes this one.
- **#414: `Override` PartNames with a well-formed content type.** The `Override` has `ContentType="application/xml"` and names a missing part. The plain `/word/nothere.xml` opens clean. Word offers recovery for each of the other nine:
    - `..`, `?query`, `#fragment` and a backslash;
    - no leading slash, an empty segment and a trailing slash;
    - an escaped `/` (`%2F`) and an escaped unreserved character (`%6F`).

    With `invalid-x` in session 3c, the query form made Word refuse the file; here it makes Word offer recovery. Word-valid and strict pass all nine.

- **#408: an escape in a folder segment.** An unreferenced `f%6Fo/xtra.xml` makes Word offer recovery, and the `foo/xtra.xml` control opens clean. Word-valid already fails it.
- **#433: a part-level relationships part.** A foreign element appended to `word/_rels/document.xml.rels` makes Word offer recovery, and the unchanged control opens clean.
- **#437: Word reads what it reaches through relationships it understands.** Three specimens open clean:
    - an unreferenced, truncated `customXml/item9.xml`;
    - a truncated `word/xtra.xml` named only by a relationship of an unknown type;
    - a truncated `word/xtra.xml` with its own `Override` and no relationship.

    Word-valid fails the last two, so they are false positives. Neither an unknown relationship type nor a declared content type makes Word read a part.

- **#409: a core-properties relationship Type with a trailing space.** A truncated core part named by such a relationship opens clean, and so does its well-formed control. Word does not read the part as core properties. Word-valid agrees and passes both (review Z F2).
- **#411, review Y: Word reads central-directory names.**
    - A `..` name that is only in the central directory makes Word offer recovery: `evil/../x.xml` with local name `x.xml`.
    - So does a central `a/../x.xml` whose unicode-path field says `x.xml`.
    - A `..` name that is only in the local header opens clean: central `word/extra.xml`, local `../evil.xml`.
    - So does a central `x.xml` whose unicode-path field says `../evil.xml`.
    - Two central entries both named `word/document.xml`, with distinct local names, make Word offer recovery, as #411's identical names do.

    Word-valid fails the two specimens Word opens clean. Its extraction judges the name JSZip loads, which comes from the local header or the unicode-path field.

- **#443: non-ASCII stored names.** Word offers recovery for any stored name holding a non-ASCII character, raw or percent-escaped, at the package root or under `word/`:
    - the CP437 byte `0x82`;
    - UTF-8 `é`, with or without flag bit 11;
    - `%C3%A9` and `%E9`.

    The ASCII controls `cafe.xml`, `word/cafe.xml` and `caf%20.xml` open clean. Word-valid passes all six recovery specimens.

Session 7 adds:

- **#414: the remaining `PartName` rules.** Each specimen is an `application/xml` `Override` for a missing part, as in sessions 4 and 5. Word offers recovery for a last segment ending with `.` (`/word/nothere.xml.`), a space, `[` and `]`, and a literal `é`. Word-valid at 9960b273 already fails all four. The `/word/nothere.xml` and `/word/no%20there.xml` controls open clean.
- **#450: a folder segment ending with `.`.** Word opens `/word./nothere.xml` (twice, once in a run of its own), `/word/sub./nothere.xml` and `/x./nothere.xml` clean. Word-valid at 9960b273 fails all four, a false positive. At 34d0ace3 word-valid warns and passes them, and strict still fails them under [M1.9].
- **#451: a percent-escaped non-ASCII `PartName`.** `/word/caf%C3%A9.xml` is a valid part name, but Word offers recovery, as it does for the non-ASCII stored names of #443. Word-valid and strict pass it.

Sessions 8–13 add:

- **#432: every part typed by the generic Default.** Typed only by `<Default Extension="xml" ContentType="application/xml"/>`, a related settings, fontTable or webSettings part makes Word offer recovery, and so do the main part and styles with their `Override` removed. Each control with the part's proper `Override` opens clean. Word-valid at 49922e9a passes all five; strict fails only the main part.
- **#443: a non-ASCII name that a relationship targets.** The styles part stored as `word/stylés.sty`, typed by an `sty` `Default`, makes Word offer recovery whether its relationship targets `stylés.sty` or `styl%C3%A9s.sty`. The ASCII `word/styles.sty` control opens clean. The unreferenced stored names `word/caf%C3%A9.xml` and `word/a%80b.xml` make Word offer recovery too (session 12). Word-valid passes all four.
- **#451 and #408: which percent-escapes Word refuses.** In an `Override` `PartName` and in an unreferenced stored name alike, Word offers recovery for an escape of a character in the RFC 2396 unreserved set, and for any escape of 0x80 or above:
    - RFC 3986 unreserved: `%41`, `%39`, `%2D`, `%2E`, `%5F`, `%7E`;
    - the RFC 2396 marks `!`, `'`, `(`, `)`, `*`: `%21`, `%27`, `%28`, `%29`, `%2A` and `%2a`;
    - 0x80 and above: `%80`, `%FF`, `%E9`.

    It opens clean `%01`, `%7F`, `%22`, `%24`, `%25`, `%26`, `%2B`, `%2C`, `%3A`, `%3B`, `%3C`, `%3D`, `%40`, `%5B` and `%7B` in a `PartName`, `%26`, `%3A`, `%5B` and `%7F` in a stored name, and a literal `!` in both. Word-valid catches only the RFC 3986 part, so it passes the marks and the escapes of 0x80 and above (false negatives).

- **#437: Word parses some related parts at open, and others only when the document uses them.** Malformed, a related settings, fontTable or webSettings part, an unused but related numbering part, and a `customXml` item named by a document `customXml` relationship each make Word offer recovery. A malformed footer referenced from `w:sectPr` makes Word refuse the file, and malformed comments referenced by a comment range make it offer recovery. The same footer, comments or footnotes, related but unused, open clean. Word-valid fails the unused footer (twice), comments (twice) and footnotes, which are false positives, and passes the `customXml` item, a false negative.
- **#453: dot-only folder segments.** `/word/.../x.xml`, `/word/..../x.xml` and `/.../x.xml` make Word offer recovery, while `/word./x.xml` opens clean again. Word-valid at 49922e9a passes the three, because the #450 tolerance caught them. At e08611b1 they break their own rule ([M1.10]) and fail word-valid.
- **#458: an `Override` without a usable `PartName`.** Without the attribute, with `PartName=""` and with `PartName="/"`, Word offers recovery, and word-valid fails all three.

Session 14 adds:

- **#459: Markup Compatibility in the content-types stream.** `xmlns:mc` declared on `Types` and left unused opens clean. `mc:Ignorable="x"` on `Types` makes Word offer recovery, alone or with an ignored `<x:Foo/>` child; word-valid at ed34e3bf passes both, and strict fails both through `xsd-error`. An ignorable namespace declaration in `[Content_Types].xml` is itself enough for Word to offer recovery. Both `mc:AlternateContent` orientations, whose Choice and Fallback each hold one `Override`, make Word offer recovery too, but each also carries `/word/a%41b.xml`, which Word refuses alone (session 11), so those two do not separate the MCE cause.
- **#464: bytes before the archive.** A 2-entry ZIP, or 4096 spaces, in front of the minimal package make Word offer recovery, with the package's offsets relative to its own start and with them rewritten as absolute. Word-valid at ed34e3bf fails the prefixed ZIP through `zip-bytes-after-eocd` and passes both space prefixes, as strict does.

Session 15 adds, for review AM's suspected findings on layers 78 and 79:

- **#514 (F4): the main document's relationships part.** `word/_rels/document.xml.rels` missing its root end tag, or zero bytes, makes Word offer recovery. Word-valid at 8252ce4f passes both, since layer 78 stopped blocking on that part; strict fails both through `xml-syntax`.
- **#515 (F6): a second `officeDocument` relationship.** Any second `officeDocument` relationship in `_rels/.rels` makes Word offer recovery: to a well-formed `alt/document.xml` with or without a main-type `Override`, to a malformed one, and to `word/document.xml` again. A well-formed `alt/document.xml` with a main-type `Override` and no relationship opens clean, so the relationship is the cause. Word-valid and strict pass the well-formed second relationship and the same-target one.
- **#516 (F8): headers, endnotes, themes and glossaries.** A malformed header stored as `hdr/header1.xml` and referenced by `w:headerReference` makes Word refuse the file, and its well-formed control opens clean. Malformed endnotes at `en/endnotes.xml` used by `w:endnoteReference`, a malformed theme at `th/theme1.xml` and a malformed glossary at `g/glossary.xml`, each named by a document relationship, make Word offer recovery. A malformed `word/header1.xml` or `word/endnotes.xml` that is related but not referenced opens clean. Word-valid passes the four stored outside `word/` and fails the two unused ones.
- **#517 (F9): generic content types.** Word offers recovery for the main part typed by a `text/xml` Default, an `application/xml` Override or a `text/xml` Override, and for styles typed by an `application/xml` Override or a `text/xml` Default. Word-valid passes all five, and strict passes all but the `text/xml` Default on the main part (`ct-undeclared-part`).
- **F5 and F7 open clean.** A styles relationship typed `http://schemas.microsoft.com/office/2007/relationships/styles` with a malformed `word/styles.xml`, a `styles` relationship in `_rels/.rels` to a malformed `word/styles2.xml`, and a comment range without `w:commentReference` with a malformed `word/comments.xml` all open clean, as word-valid predicts.

Session 16 adds, for review AR's suspected items and its finding F1 on layers 89–92:

- **#539: a header referenced only from the glossary.** A `w:headerReference` only in the `w:sectPr` of a glossary `w:docPartBody`, naming a malformed `word/glossary/header9.xml` through the glossary document's own relationships part, makes Word offer recovery. Its well-formed control opens clean, so the malformed header is the cause. Word-valid at 98902c85 passes both; strict fails the malformed one through `xml-syntax`.
- **Endnotes referenced only from a footnote open clean.** A `w:endnoteReference` only inside a footnote (the main document references the footnote) with a malformed `word/endnotes.xml` opens clean, as does its well-formed control. Word does not follow every story's references, and word-valid passes both.
- **#540: a MIME parameter on a content type.** Word offers recovery for the main part's `Override` with the main type plus `; charset=utf-8`, the styles `Override` with the styles type plus `; charset=utf-8`, and the styles `Override` `application/xml; charset=utf-8`. Word-valid and strict at 98902c85 pass all three.
- **#535 (F1): a main part stored elsewhere, typed by a generic Default.** A main part stored as `word/document.bin` typed by `Default Extension="bin" ContentType="text/xml"`, and one stored as `docProps/document.xml` typed by a `text/xml` `Default` for `xml`, each make Word offer recovery. Word-valid at 98902c85 fails both through `word-part-content-type-generic`, and strict passes both. A `.bin` main typed by a `bin` `Default` with the main type opens clean.

Session 17 adds, for the questions session 16 left open:

- **#549: the glossary reads like a main document.** The glossary document's own relationships part, missing its root end tag or zero bytes, makes Word offer recovery, even when the glossary references nothing. Malformed footer, footnotes, endnotes and comments parts that the glossary references (`w:footerReference` in its `w:sectPr`; `w:footnoteReference`, `w:endnoteReference`, `w:commentReference` in a `w:docPartBody`) each make Word offer recovery, and each well-formed control opens clean. A malformed header the glossary relates but does not reference opens clean. Word-valid at 3ebe3e7f passes all of them except the malformed footnotes, which it fails through `word-footnote-reference-missing`.
- **#550: content types must equal the part's type, ignoring case.** Word offers recovery for `; charset=utf-8` on the settings, fontTable, webSettings and referenced-header `Override`s; for `;charset=utf-8` (no space) and `; foo=bar` on the main part; for a trailing space on the styles type; and for styles typed by a `Default` `application/xml; charset=utf-8`. The main and styles types in upper case open clean, as do the settings and header controls with the plain type. Word-valid passes every refused shape, and strict fails only the trailing space (`xsd-error`).

Session 18 adds, for review AS's suspected item S3 (#441):

- **A literal non-ASCII stored name is refused alone.** An unreferenced well-formed `word/café.xml` makes Word offer recovery in NFC and in NFD, stored alone, as do the NFC/NFD part pair, an NFC/NFD folder pair and a case pair. Word-valid at ab1fba79 fails all five (`opc-part-name-word-refused`, `opc-equivalent-part-names`), so its failure of NFC/NFD pairs agrees with Word.

Session 19 adds, for the glossary's eagerly parsed parts, which #549 left unobserved:

- **#562: the glossary's own styles, settings, fontTable, webSettings and numbering are read.** Each specimen pairs a reached glossary that references no story with one part related from the glossary's own relationships part (`word/glossary/styles.xml`, `settings.xml`, `fontTable.xml`, `webSettings.xml` or `numbering.xml`, each with its Word `Override`). When that part is missing its root end tag, Word offers recovery, for all five types; every well-formed control opens clean. Word-valid at 4c86cbfe passes all ten. Strict fails the malformed ones through `xml-syntax`, and every glossary specimen through the strict-only `paraid-missing-element` on the glossary paragraph, which the session 16 and 17 glossary controls also carried while opening clean.

Session 20 adds, for the items the open list named after session 19:

- **#569: a reached glossary's theme part is read; its customXml part and a nested glossary are not.** Each specimen pairs a reached glossary that references no story with one part its own relationships part relates. A Word theme missing its root end tag at `word/glossary/theme/theme1.xml` gets the recovery offer, and the well-formed theme opens clean. A truncated `customXml/item1.xml` (target `../../customXml/item1.xml`) and an unclosed nested `glossaryDocument` (`word/glossary/glossary2.xml`) open clean, as do their controls. Word-valid at 52fdbd8b passes all six. Strict fails the malformed theme through `xml-syntax`, and every glossary specimen through the strict-only `paraid-missing-element` on the glossary paragraph. The well-formed theme is `word/theme/theme1.xml` of `tests/fixtures/working/package.word-anchor-open-repaired.docx`, read and not modified.
- **#570: a MIME parameter on numbering, theme, a used footer, footnotes, endnotes or comments is refused.** Each specimen is the minimal package plus one part the main document relates. The lazy types are also used: a body `w:footerReference`, a `w:footnoteReference`, a `w:endnoteReference` or a `w:commentReference`. When the part's `Override` carries its own type plus `; charset=utf-8`, Word offers recovery for all six. With the exact type, each opens clean. The same parameter on the main document's glossary part opens clean. Word-valid at 52fdbd8b passes all seven. Strict reports `word-part-content-type-inexact` for numbering, the footer, footnotes, endnotes and comments, but not for theme.
- **#571: numbering and theme typed by the generic Default are refused.** A related `word/numbering.xml` or `word/theme/theme1.xml` with no `Override`, so typed by `Default Extension="xml" ContentType="application/xml"`, gets the recovery offer. With its exact `Override`, each opens clean. Word-valid at 52fdbd8b passes both. Strict reports `word-part-content-type-generic` for numbering and `ct-undeclared-part` for theme.
- **#549: footnotes, endnotes and comments a glossary relates but does not reference are not read.** Each part, missing its root end tag and related from the glossary's own relationships part with no reference in the glossary, opens clean, as session 17 observed for the header. Word-valid passes all three, as it should.

Session 21 adds, for the open list's padded and unused-part item and one glossary part:

- **#570: padding is refused on the same six parts.** Each part is related and used exactly as in session 20, and its `Override` carries its own type plus one trailing space. Word offers recovery for numbering, theme, the footer, footnotes, endnotes and comments. Word-valid at cb36e27a passes all six. Strict reports `word-part-content-type-inexact` for all but the theme, and an `xsd-error` on `[Content_Types].xml` for all six.
- **#570: an unused lazy part with a parameterized type is not judged by Word.** The main document relates a footer, footnotes, endnotes, comments or header part but never references it, and the part's `Override` carries its type plus `; charset=utf-8`. All five open clean. Word-valid passes them, as it should; strict reports `word-part-content-type-inexact` by the spec.
- **#579: a parameter on a reached glossary's styles part is refused.** Session 19's shape — a reached glossary that references no story, whose own relationships part relates `word/glossary/styles.xml` — with the styles `Override` carrying its type plus `; charset=utf-8` gets the recovery offer, and the exact-type control opens clean. Neither profile at cb36e27a reports a content-type finding; strict fails both only through the strict-only `paraid-missing-element` on the glossary paragraph.

Session 22 adds, for the items adversarial review AU suspected (ledger on #550):

- **#579 (S1): a parameter on a header the glossary references is refused.** Session 16's shape: a reached glossary whose `docPartBody` ends with a `w:sectPr` referencing `word/glossary/header9.xml` through the glossary's own relationships part. With the header's `Override` carrying its type plus `; charset=utf-8`, Word offers recovery; with the exact type, it opens clean. Neither profile at cb36e27a reports a content-type finding.
- **#581 (S2): an empty main-document content type is refused.** `<Override PartName="/word/document.xml" ContentType=""/>` gets the recovery offer. Word-valid at cb36e27a passes it; strict fails it only through the XSD (`xsd-error` on `[Content_Types].xml`).
- **S4: a trailing NO-BREAK SPACE is refused as a trailing space is.** The styles `Override` with its type plus U+00A0 gets the recovery offer, and so does the U+0020 control (session 17's shape). Word-valid already reports `word-part-content-type-inexact` for both.
- **S5: folding case does not excuse a parameter.** The main document's type upper-cased plus `; CHARSET=UTF-8` gets the recovery offer, and the upper-cased type alone opens clean, as session 17 observed. Word-valid already reports the first and passes the second.
- **S6: a glossary header referenced only from an unselected `mc:Fallback` is not read.** The glossary's `w:sectPr` holds an `mc:AlternateContent` whose `mc:Choice Requires="w14"` is empty and whose `mc:Fallback` holds the header reference; the header is unclosed. Word opens it clean, as it does the well-formed control. With the reference in the `mc:Choice` instead, Word offers recovery. Word-valid already matches all three: a warning for the header only the Fallback references, an `xml-syntax` error for the one the Choice references.

Session 23 adds, for the items adversarial review AW suspected (ledger on #591):

- **#595: a reached glossary's theme typed by the generic Default is refused.** Session 20's #569 shape — a reached glossary that references no story, whose own relationships part relates `word/glossary/theme/theme1.xml` — with no `Override` for the theme, so `Default Extension="xml" ContentType="application/xml"` types it, gets the recovery offer. With the exact theme type in an `Override`, it opens clean. Word-valid at 8690b11c passes both; strict fails the first through `ct-undeclared-part`, and both through the strict-only `paraid-missing-element` on the glossary paragraph.
- **#596: a parameter on a story part the glossary references is refused.** Session 17's shapes — a reached glossary that references `word/glossary/footer9.xml` from its `w:sectPr`, or footnotes, endnotes or comments from its `docPartBody` — with the part's `Override` carrying its type plus `; charset=utf-8`, get the recovery offer for all four. With the exact type, each opens clean. Word-valid at 8690b11c passes all eight; strict reports `word-part-content-type-inexact` for the four parameterized parts.

Session 24 adds, for the items adversarial review AX suspected (ledger on #599):

- **#600: a header or footer declared with the other story's type is refused.** A footer the main document references from its `w:sectPr`, declared by an `Override` with the exact header type, gets the recovery offer, and so does a header it references declared with the exact footer type. A footer a reached glossary references (session 17's shape) gets the recovery offer when declared with the header type, exact or plus `; charset=utf-8`. Each control with its own exact type opens clean. Word-valid at 70381216 passes all four refused files, and strict fails them only through the strict-only `paraid-missing-element`, which their controls share: no rule reports the cause.
- **#601: a reached glossary's styles part typed by the generic Default is refused.** Session 21's glossary styles shape (an empty `w:styles` the glossary's own relationships part relates) with no `Override`, so `Default Extension="xml" ContentType="application/xml"` types it, gets the recovery offer. With the exact styles type in an `Override`, it opens clean. Word-valid at 70381216 passes both; strict fails both only through `paraid-missing-element`.
- **#595: a `text/xml` `Override` on a reached glossary's theme is refused.** It gets the recovery offer, and the exact-type control opens clean. Word-valid at 70381216 already rejects it through `word-part-content-type-generic` (layer 127), so this confirms an inference rather than finding a gap.

Session 25 adds, for the drift the Validator Diff Report flagged on #322 (#271):

- **#271: the profile-less default flips three diff-set fixtures to valid, and Word agrees.** `scripts/validate-diff.ts` calls `validate()` with no profile, and #322 makes word-valid the DOCX default, so `broken/footnotes.duplicate-paraid.docx`, `eigen/blue-bold-centered-demo.id-paraid-overflow.docx` and `eigen/1-5-line-spacing.id-paraid-overflow.docx` went from invalid (`id-paraid-overflow`) to valid. Their strict and word-valid verdicts are identical at the base (9aaeeeae) and the head (4f1372c5). Word opens all three clean, so the new default verdict matches Word. The `UNREADABLE_CONTENT` specimen in `word-invalid-fixtures/` is a different file, `unknown/unknown/footnotes.duplicate-paraid.docx`.

Session 26 adds, for the items adversarial review AY (#602) left for a probe:

- **#606: Word refuses a `w:headerReference` whose `r:id` names a footer-type relationship.** It offers recovery whether the target is a `w:hdr` part typed `footer+xml`, `footer+xml; charset=utf-8`, `header+xml` or `styles+xml`, or a well-formed `w:ftr` part typed `footer+xml`. The relationship type is the cause: a story part whose root is the other story's element, reached through a matching reference and relationship (a `w:hdr` part as a footer, a `w:ftr` part as a header), opens clean. `s26c` widens it: the mirror (a `w:footerReference` naming a header relationship), the same references in a reached glossary's `w:docPartBody` `w:sectPr`, and a `w:headerReference` naming the styles relationship are all refused, and the matching glossary footer opens clean. In the main document and in a reached glossary, a header or footer reference whose relationship is of another type makes Word offer recovery.
- **#607: an unused header relationship does not change what Word parses.** A footer the body reads through `w:footerReference`, which an unreferenced header relationship also targets, is refused when typed `header+xml` and opens clean when typed `footer+xml`.
- **#610: a glossary header typed `footer+xml` is refused,** like session 24's glossary footer typed `header+xml`.

Session 27 adds, for the items adversarial review AZ (#611) left for a probe:

- **#613: Word accepts exactly two relationship Types for a header or footer reference.** For a body `w:headerReference`, the Transitional `http://schemas.openxmlformats.org/officeDocument/2006/relationships/header` and the ISO Strict `http://purl.oclc.org/ooxml/officeDocument/relationships/header` open clean. `http://example.com/header`, `…/relationships/custom/header`, `…/relationships/HEADER`, the URI padded with spaces or wrapped in tab and newline character references, and the bare `header` are all refused. The footer side is the same (`s27c`). Word-valid at 9eb10acb passed `http://example.com/…` and `…/custom/…`, because its check tested only the end of the Type.
- **A duplicate relationship Id with entries of different types was refused in both orders.** In each specimen one entry's target also had a content type that disagreed with that entry's relationship type, so session 27 cannot separate the duplicate Id from that mismatch. Session 29 separates them (below).
- **The relationship type also decides in a paragraph-level `w:pPr/w:sectPr` and inside a `w:sectPrChange`.** A `w:headerReference` naming a footer relationship is refused in either place. The same reference naming a header relationship opens clean inside a `w:sectPrChange`, although `CT_SectPrBase` has no header reference, so strict still rejects it on schema.

Session 28 adds:

- **#614: Word accepts exactly two relationship Types for a `w:hyperlink`, too.** With TargetMode `External`, the Transitional `http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink` and the ISO Strict `http://purl.oclc.org/ooxml/officeDocument/relationships/hyperlink` open clean. `http://example.com/hyperlink`, `…/relationships/custom/hyperlink` and `…/relationships/HYPERLINK` are refused. Word-valid and strict at 9eb10acb passed the first two refused Types, because `word-hyperlink-relationship` tested only the end of the Type.

Session 29 adds:

- **#615: Word refuses any duplicate relationship Id in the main document's relationships part and in the package relationships part.** In `word/_rels/document.xml.rels`, Word refused a header reference's Id naming a footer relationship first and a header relationship last, the reverse order, the same header relationship listed twice, and two unreferenced External hyperlink relationships sharing an Id; every target was correctly typed. Two unreferenced hyperlink relationships sharing an Id in `_rels/.rels` were refused too. The same pair in a header part's own `word/_rels/header9.xml.rels` opened clean. Word-valid at 4a5926d3 passed every refused specimen except `headerref-dup-id-header-first-footer-last`, whose last entry `word-header-footer-relationship` rejects.
- **Review BA's S1: the `https:` spelling is refused.** The Transitional header, footer and hyperlink Types with `https:` in place of `http:` were all refused, as word-valid and strict at 4a5926d3 already report.

Session 30 adds:

- **#617: Word refuses a duplicate relationship Id in a reached glossary's own relationships part.** Two unreferenced External hyperlink relationships sharing an Id in `word/glossary/_rels/document.xml.rels`, in session 26's clean glossary footer shape, were refused; the shape without them opened clean. Word-valid at 77d01c46 passes it, because #615 blocks only the package and main-document `.rels`.
- **Review BB's S2: a duplicate Id in the relationships part of a document Word does not reach opens clean.** With the main document moved to `word/main.xml`, the same pair in an orphan `word/_rels/document.xml.rels` (beside an orphan `word/document.xml`) opened clean, as did the shape without it and the moved main document alone.
- **#615's resolution of the main document is right.** The same pair in the moved main document's own `word/_rels/main.xml.rels` was refused, as word-valid at 77d01c46 reports.

Session 31 adds:

- **#618: Word refuses a duplicate relationship Id beside a story root stored as `.bin`.** With the main document stored as `word/document.bin`, two unreferenced External hyperlink relationships sharing an Id in `word/_rels/document.bin.rels` were refused; so was the same pair in `word/glossary/_rels/document.bin.rels` with session 26's glossary stored as `word/glossary/document.bin`. Both renamed shapes opened clean without the pair. No profile at ceb5c884 reports `rels-id-duplicate` for either, because the duplicate walk visits only the `.rels` of owners whose names end in `.xml`; word-valid passes both.

Session 32 adds:

- **#619: Word offers recovery for a story reference whose `r:id` names no relationship.** A body `w:footerReference w:type="default" r:id="rId9"` with `word/_rels/document.xml.rels` present but holding no `rId9` was refused. Word-valid at 6e3cda3e passes it: `word-header-footer-relationship` leaves an `r:id` that names no relationship to `rels-id-missing`, which is strict-only. The same reference with the main document's `.rels` removed was refused too, as word-valid already reports (`rels-missing-sidecar`).
- **#620: a main document stored as `word/document.bin` is not checked as XML.** Truncated (its closing `</w:body></w:document>` removed), it made Word fail to open the file, as the `.xml` twin does, but word-valid and strict at 6e3cda3e both pass it. Its two footer-reference shapes were refused like their `.xml` twins, and word-valid passes both; strict passes the one whose `.rels` holds no `rId9`.

Session 33 adds:

- **#623: Word refuses a story reference whose `r:id` is empty or missing.** A body `w:headerReference` or `w:footerReference` with `r:id=""` got a recovery offer (the header in `s33a`, the footer in `s33c`). One with no id in either relationships namespace got an open error (the footer in `s33c`, the header in `s33e`). An id in any other namespace counts as none: a footer reference whose only id was `x:id` (`xmlns:x="urn:x"`) got the same open error, dangling or naming a valid footer relationship (`s33d`). Word-valid at 8b79bc78 passes all six; strict catches the id-less ones only through the XSD (`r:id` is required) and passes the empty ones.
- **#624: a story reference in the ISO Strict relationships namespace needs the sidecar too.** With the main document and styles in the ISO Strict WordprocessingML namespace, a body `w:footerReference r:id="rId9"` whose `r` prefix is bound to the ISO Strict relationships namespace was refused with `word/_rels/document.xml.rels` removed (`s33a`). The same Strict package without the reference opened clean (`s33c`), so the missing sidecar alone is not the cause. With the sidecar kept but holding no `rId9`, the reference was refused as word-valid reports (`s33c`). Word-valid at 8b79bc78 passes the no-sidecar shape, because `rels-missing-sidecar` looks only for Transitional-namespace ids.
- **#625: Word judges a story root by the relationship that reaches it, not by its name.** A main document, and a reached glossary, each stored as `word/header1.xml` (with its package relationship or glossary relationship, `.rels` and Override renamed with it) opened clean (`s33b`). With no `.rels` beside a footer reference (the main document's body one, or the glossary's own), both were refused, like the ordinary-name glossary calibration. Word-valid at 8b79bc78 passes both renamed shapes, because its `word/header|footer\d*.xml` basename exemption drops `rels-missing-sidecar` there; strict reports it.
- **#631 refuted: Word reads the ISO Strict `r:id` on a Transitional story reference.** A Transitional `w:footerReference` whose only id was an `rs:id` (`xmlns:rs` bound to the ISO Strict relationships namespace) naming a real footer relationship opened clean, and the PDF Word wrote rendered the footer (`s33c`). Dangling, it got the recovery offer of a dangling Transitional `r:id`, not the open error of a reference with no id. `word-header-footer-relationship` already resolves both namespaces (#606, #619).
- **#632: Word applies markup compatibility to relationships parts before it judges their children.** In `word/_rels/document.xml.rels`, session 26's footer relationship opened clean, the footer rendered, in three shapes: inside an `mc:Fallback` beside an `mc:Choice` requiring a namespace Word does not understand (`s33d`); inside an `mc:Choice` requiring `w14` with an empty `mc:Fallback` (`s33e`); and kept beside a foreign `<x:Wrap/>` whose prefix the root declares `mc:Ignorable` (`s33e`). `_rels/.rels` with its officeDocument relationship inside such a Fallback opened clean too (`s33e`). A foreign `<x:Wrap/>` left inside the selected Fallback was refused (`s33e`), as #433's undeclared one is. Word-valid at 5cd8ada8 rejects all four clean shapes, through `opc-relationships-structure` (and, for `_rels/.rels`, `word-main-document-part`), which judge the stored XML.

Session 34 adds:

- **#634: Word reads a part reached through a relationship markup compatibility selects, and refuses its defects as it does through a direct relationship.** Each specimen moved one relationship into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` and gave the part it reaches a defect; each ran beside its direct-relationship twin. A truncated main document reached through `_rels/.rels`'s Fallback officeDocument relationship got an open error, as its twin did (`s34a`). With that Fallback main document, a zero-byte `word/_rels/document.xml.rels` got a recovery offer, as its twin did (`s34a`). A truncated `docProps/core.xml` reached through a Fallback core-properties relationship got a recovery offer, as its twin did (`s34b`). Session 26's footer typed as a header (#600), its relationship in the Fallback of `word/_rels/document.xml.rels`, got a recovery offer, as its twin did (`s34b`). Word-valid at ef5d8107 (layer 131, #632's fix) passes all four wrapped shapes and rejects every twin: `word-read-parts` and `properties-parts` read the stored `.rels`, so the reached parts are not Word-read and their errors are demoted. Before #632's fix the stored `mc:AlternateContent` child was itself a blocking `opc-relationships-structure` error.
- **#635: Word judges relationship Ids in the processed relationships part.** `_rels/.rels` holding a direct `rId1` (officeDocument) and a second `rId1` (styles) inside the Fallback got a recovery offer, as two direct `rId1` did (`s34a`; #615's session 29 class). Word-valid at ef5d8107 passes it: the legacy relationship walk collects the stored direct children only, and finds no duplicate.
- **#636: Word honours markup-compatibility errors in relationships parts.** `mc:MustUnderstand="foo"` (`xmlns:foo="urn:foo"`, a namespace Word does not understand) on the `_rels/.rels` root got a recovery offer and, after it was declined, "Word experienced an error trying to open the file."; Word's process then exited (`s34c`, probed alone beside a clean control after Word went down twice during `s34b`). Word-valid at ef5d8107 passes it with no finding. Session 26's footer relationship inside an `mc:Choice` whose `Requires` prefix is undeclared, with an empty Fallback, got a recovery offer (`s34d`); word-valid already rejects it, through `word-header-footer-relationship`, because the relationship disappears.

Session 35 adds:

- **#638: Word does not resolve every relationship id `rels-missing-sidecar` counts.** Each specimen had a non-empty relationship id and no `.rels` beside its part, and Word opened each clean while word-valid at 9ac8d583 rejected each with a blocking `rels-missing-sidecar`. In parts Word does not read (`s35a`): an unreferenced `word/xtra.xml` holding an ISO Strict `rs:id`, and its Transitional `r:id` twin; a `docProps/app.xml` no relationship names, holding an `rs:id`; an ISO Strict glossary no `glossaryDocument` relationship reaches, holding an `rs:id` footer reference. In a part Word reads (`s35a`): `rs:id` on `w:name` in `word/styles.xml`, an element the schema gives no relationship attribute. In the main document with its `.rels` removed (`s35b`): an `a:blip` `rs:embed` inside an `mc:Choice` whose `Requires` Word does not understand, beside an empty `mc:Fallback`, and its Transitional `r:embed` twin. The Transitional twins blocked before #624 too; #624 exposed the ISO Strict shapes.
- **Word resolves a story reference inside `w:sectPrChange`.** A `w:footerReference rs:id="rId9"` inside `w:sectPrChange/w:sectPr` of the body `w:sectPr`, the main document's `.rels` removed, got a recovery offer (`s35b`); word-valid already rejects it through `rels-missing-sidecar`. Deleted section properties are read, not skipped.
- **#623's missing-id rule holds outside the body `w:sectPr`.** A `w:footerReference` with no id inside `w:sectPrChange/w:sectPr`, as a direct `w:body` child, and in a paragraph-level `w:pPr/w:sectPr` each got "Word experienced an error trying to open the file." (`s35b`), as `word-header-footer-relationship` already reports. `r:id=""` beside `x:id="rId9"` (`urn:x`) and `r:id=" "` each got a recovery offer (`s35c`), as the check's message says.

Session 36 adds:

- **#644: Word rejects markup-compatibility errors in the package relationships part and in every story root's own sidecar, found by relationship, and ignores them in other sidecars.**
    - **Malformed sibling.** The specimens append a malformed `mc:AlternateContent` sibling to a relationships part: an `mc:Choice` whose `Requires` prefix `nope` is undeclared, beside an empty `mc:Fallback`. It selects nothing and removes no relationship.
        - Recovery offered: `_rels/.rels`, `word/_rels/document.xml.rels` and the glossary document's sidecar (`s36a`); the sidecar of a main document stored as `word/doc2.xml` (`s36e`).
        - Clean open: a stray `word/_rels/document.xml.rels` beside that renamed main document (`s36a`); the styles and footer sidecars (`s36d`).
    - **`mc:MustUnderstand` on the root** (namespace `urn:foo`, which Word does not understand).
        - Recovery offered: the main document's sidecar (`s36b`); the renamed main document's sidecar and the glossary's (`s36e`).
        - Clean open: the stray sidecar (`s36e`).
        - On a `Relationship` in `_rels/.rels` it got a recovery offer (`s36b`).
    - **Word-valid at dd5a3da2** passes the package, glossary and renamed-main shapes and every sidecar-root `mc:MustUnderstand`, and rejects the stray sidecar. #632 caused the package and glossary misses: before it, `opc-relationships-structure` rejected them.
    - **Session 34's `s34d` recovery** comes from the malformed AlternateContent itself, not from the footer relationship it hid. The sibling form, which hides nothing, got the same offer in `word/_rels/document.xml.rels`.
    - **Fallback-only and foreign-branch AlternateContent** in that part got recovery offers too (`s36b`), as #636 reports.
- **#645: Word does not load a chart that no drawing references.**
    - **Unreferenced.** A chart part with `<c:externalData r:id="rId1"/>` and no `.rels`, related from `word/_rels/document.xml.rels` but referenced by no drawing, opened clean in `word/charts/` and in `charts/` (`s36b`). Word-valid at dd5a3da2 (and before #638) rejects both with `rels-missing-sidecar`.
    - **Referenced.** With an inline drawing's `c:chart r:id` referencing it, the same chart got a recovery offer in both places (`s36d`), as word-valid reports. #638's outside-`word/` rule holds.
    - **Control.** Without `c:externalData`, the referenced chart opened clean.
- **#640, #646: Word applies markup compatibility to the `_rels/.rels` root** (`s36c`).
    - A root `mc:AlternateContent` whose Fallback holds the `Relationships` element opened clean. Word-valid at dd5a3da2 rejects it with `opc-relationships-structure` (#646).
    - One whose Fallback holds two bare `Relationship` elements got a recovery offer. `validate()` throws `HierarchyRequestError` on it at dd5a3da2 (#640).
- **Word agrees with word-valid on the layer 131 review's remaining suspects** (`s36c`).
    - Session 26's footer relationship inside an ignorable `x:Wrap` that `mc:ProcessContent` names opened clean.
    - The same wrapper without `mc:ProcessContent`, which drops the relationship, got a recovery offer.
    - A duplicate `rId2` split across an understood `w14` Choice and its own Fallback, beside the direct `rId1`, opened clean.

Session 37 adds:

- **#644: Word ignores markup-compatibility errors in sidecars that are not a story root's** (`s37a`).
    - The malformed sibling from session 36, in `word/_rels/settings.xml.rels`, `word/_rels/numbering.xml.rels` and `word/_rels/header1.xml.rels`, opened clean in each. `release/0.53.0-rc.2` (ab2e324f) rejects all three with `opc-relationships-structure`; layer 131 passes them.
    - `mc:MustUnderstand` on the root of `word/_rels/styles.xml.rels` and `word/_rels/footer1.xml.rels` opened clean. Both commits pass them.
    - Together with session 36, every sidecar observed outside the package part and the story roots opened clean: stray, styles, footer, settings, numbering and header.
- **#645: Word reads a chart's reference in the processed markup-compatibility view** (`s37b`).
    - The referenced chart from `s36d` with its drawing only inside an `mc:Choice` Word does not select (`Requires="foo"`, empty Fallback) opened clean. Layer 131 rejects it with `rels-missing-sidecar`; #645's fix (76bb5622) passes it.
    - The same drawing inside a selected `mc:Choice` (`Requires="w14"`) got a recovery offer, then "Word experienced an error trying to open the file.", as word-valid reports. Without `c:externalData` it opened clean.
- **#647: a chart reached by a chart and an image relationship, and referenced by nothing, opened clean** (`s37b`). Word-valid rejects it at every commit tested, including 76bb5622, which keeps a part a second relationship type reaches on the reach-based rule.

Session 38 adds:

- **#646: Word resolves the `_rels/.rels` root through markup compatibility** (`s38a`).
    - A root that resolves to the package part's whole `Relationships` element opened clean in three wrappers: the `mc:AlternateContent` whose Fallback holds it (`s36c`'s shape again, byte-identical part), a selected `mc:Choice` (`Requires="w14"`, empty Fallback), and an Ignorable `mc:ProcessContent` wrapper. `release/0.53.0-rc.2` (ab2e324f) and the layer 132 head (3788f719) reject all three with `opc-relationships-structure`; #646's fix (4295889a) passes them.
    - The same element in an `mc:Choice` Word does not select (`Requires="foo"`), beside an empty Fallback, leaves no root: Word offered recovery, then "Word experienced an error trying to open the file.". Every commit rejects it.

Session 39 adds:

- **#661: Word reads a chart's missing sidecar only through a referenced chart relationship, whichever reached part relates it** (`s39a`, `s39c`).
    - Six chart shapes beyond sessions 36 and 37 opened clean with the chart relationship's Id unused: the chart related from a referenced header's sidecar, from a reached glossary's footnotes sidecar, and from the glossary document's own sidecar; the main document's drawing only in an `mc:Fallback` Word does not select (beside a selected empty `w14` Choice); two `chart` relationships to the part, neither named; and a relationship targeting `CHARTS/%63hart1.xml`, an OPC-equivalent spelling of the stored name. `release/0.53.0-rc.2` (ab2e324f) and the layer 132 head (3788f719) reject all six with `rels-missing-sidecar`; #645's fix (4295889a) passes them.
    - Each shape's referenced twin got the recovery offer (`s39c`), most followed by "Word experienced an error trying to open the file.": the drawing in the header, in the glossary's footnotes or document, in a selected Fallback (beside an unselected `foo` Choice), naming one of two chart relationships, or naming the equivalent-target relationship. Every commit rejects all six with `rels-missing-sidecar`. The first four twins change only the reference. The last two also replace their unreferenced shape's s36b bare chart with the s36d clustered bar chart, so for those two pairs the chart changes along with the reference ([#669](https://github.com/jandira-tech/docx-validate/issues/669)). Word opened an unreferenced clustered bar chart clean in the other four shapes, and an unreferenced bare chart clean in s36b.
- **#662: Word resolves compound package-root wrappers as it resolves single ones** (`s39b`). Six `_rels/.rels` roots that markup compatibility reduces to the package part's one `Relationships` element opened clean: a Fallback holding a second wrapper, three nested wrappers, an unselected `foo` Choice before a selected `w14` Choice that holds it, the first of two `w14` Choices holding it (the second holds a foreign element), the Fallback wrapper carrying `mc:MustUnderstand="w14"`, and the Fallback wrapper around a `Relationships` element that declares `mc:Ignorable="foo"` and holds a `foo:bad` child. ab2e324f rejects all six with `opc-relationships-structure` and `word-main-document-part`, 3788f719 with `opc-relationships-structure`; 4295889a passes them, and strict still rejects them through the XSD walk.

Session 40 adds:

- **#653: Word opens the paragraph-id repair's output with w14 declared and ignorable on the root, as it opens the earlier output** (`s40a`). The repaired main document, taken from `repairMissingParaIds` itself, opened clean for a root with neither `w14` nor `mc` (the root gains both and `mc:Ignorable="w14"`), one listing `w15` (`mc:Ignorable="w15 w14"`) and one binding the compatibility namespace to `compat` (`compat:Ignorable="w15 w14"`). Release's output, with `xmlns:w14` on each stamped paragraph and row and no Ignorable entry, opened clean too. Every commit passes all four; the earlier output's `mce-extension-not-ignorable` is a schema-preprocessing warning, which Word-valid does not emit.
- **#665: Word does not resolve a `TargetMode="External"` relationship's target as a part** (`s40a`, `s40b`). External hyperlinks to `file:///missing.rels`, `file:///C:/docs/_rels/missing.xml` and `../customXml/missing.xml`, the targets Word-valid's `rels-broken` blocking keeps, opened clean as direct children of `word/_rels/document.xml.rels` and inside a selected `w14` Choice, as did `file:///missing.rels` named by a `w:hyperlink` and the non-blocking `file:///C:/missing.pdf`. f3bbf27c rejects the seven blocking-target shapes under Word-valid with `rels-broken` and all eight under strict; 0e06e03e passes them under Word-valid, and strict rejects only the Choice placements, through `opc-relationships-markup-compatibility` (#632).

Session 41 adds:

- **The 56 package fixtures layer 136 pins: Word rejects all 29 broken ones and opens all 27 twins clean, exactly as word-valid says** (`s41a`–`s41h`, two runs each).
    - Word refused 9 of the broken fixtures with "Word experienced an error trying to open the file.": `drawing-arc-radius`, `word-anchor-open`, the three `word-drawing-extent-negative*`, `word-empty-drawing`, `word-row-without-cell`, `word-sdt-id-empty` and `word-text-contains-paragraph`. It offered recovery for the other 20, including the three ZIP-envelope defects (`zip-bytes-after-eocd`, `zip-concatenated-copy` and `zip-eocd-comment-overrun`).
    - c0a244f5's word-valid rejects each broken fixture with its own defect code and passes every twin, so it agrees with Word on all 56.
    - Strict rejects 26 of the twins as well, for reasons other than their pair's defect, mostly `paraid-missing-element` (24), `style-default-missing` (15) and the XSD walk (12). Only `working/package.word-move-from-text.docx` passes strict.
    - The manifest now binds these outcomes to the fixtures' hashes. The 29 broken entries had carried `unknown` because Word had never opened them.

Session 42 adds:

- **#629: Word rejects every kind of stored item name the package view refuses** (`s42a`, `s42b`, two runs each).
    - Beside a valid package, one unreferenced, well-formed entry stored as `/word/xtra.xml`, `\word\xtra.xml`, `C:/word/xtra.xml`, `c:xtra.xml`, `word/./xtra.xml` or `word/.../xtra.xml` drew the unreadable-content offer in both runs and both readings. So did `word/a/../xtra.xml` with the name in both headers, as session 3 found for a `..` name only in the central directory.
    - The same entry stored as `word/xtra.xml` opened clean, as did both minimal controls.
    - `word//xtra.xml` (an empty segment) never opened, but its exact dialog is `unknown`. Three readings show the unreadable-content offer. Run 1's outcome table recorded the open error instead, because the driver could not read the first offer's text and logged only the error that followed it.
    - b6b80433's word-valid and strict reject all eight with `opc-item-name-refused` and `package-extract-failed`, and word-valid passes the name control and the minimal control. So word-valid agrees with Word on all 11 rows, and the check's Word-blocking classification rests on observation.

Session 43 adds:

- **#629: an empty segment draws the same offer** (`s43a`, two runs).
    - Session 42's `629-empty-segment` (`word//xtra.xml`), copied byte for byte and alone in its chunk, drew the unreadable-content offer in both runs and both readings; declining it brought the open error. Session 42's `unknown` was the reading, not Word: there, run 1's outcome table had recorded only the error that followed the offer.
    - The minimal control opened clean in both runs.
    - 6473f54b's word-valid and strict reject the specimen with `opc-item-name-refused` and `package-extract-failed` and pass the control, so word-valid agrees with Word on every stored-name kind the package view refuses.

Session 44 adds:

- **#647: an image relationship never makes Word load its target's relationships** (`s44a`, `s44b`, two runs each).
    - The bare chart, with no sidecar, opened clean when only an image relationship reaches it, under `word/` and outside it, and when an inline picture's `a:blip r:embed` names that relationship.
    - Reached by an image and a chart relationship, it opened clean unreferenced (s37b's specimen, again) and when only the picture references it; the drawing whose `c:chart r:id` names the chart relationship drew the open error.
    - The picture naming a chart part with no `c:externalData` opened clean: Word shows no dialog for a picture whose bytes are not an image.
- **#647: unreferenced diagramData, oleObject and hdphoto reaches open clean** (`s44b`, `s44c`, two runs each), under `word/` and outside it. Their referenced shapes were not shown to Word.
- 37a691ce's word-valid rejects all 12 shapes that opened clean with `rels-missing-sidecar`, and agrees with Word only on the referenced chart and the controls. Strict rejects every specimen but the controls: the bare chart fails its schema even without `c:externalData`.

## Not observed

Session 1. Another session began driving Word by 02:28Z: its first log line is at 02:28:14Z, and its map file was written at 02:27:55Z. Its preflight closes every open document, so rows observed from 02:26Z on were not treated as evidence. Session 2 observed all of them again (below).

Session 2. Every record now carries a guard. Before and after each open, the probe lists the processes driving Word that it did not start itself: an `osascript` executable, or the other session's `word_pdf`/`word_redline` scripts. It also notes whether that session's log grew. A record with any such process goes to an inconclusive file instead of the table.

- The first run, at 03:08Z, matched on command-line text, not on executables: its own shell and two review agents whose prompts forbid osascript. All ten of its records were set aside, and the guard was fixed. The 03:10Z run repeated the same ten specimens with a clean guard and identical outcomes.
- At 03:19:33Z the other session started a Word batch mid-run, and the last two records were set aside.

Session 3 observed every specimen listed for it after session 2, except as noted here.

- The first session 3 batch, at 04:38Z, ran in the default mode but wedged at item 8: Word was slow to refuse the encoding specimens, and the driver's replays queued opens of staged files it had already deleted. Its rows were not used. A serial re-run with `--no-one-osascript` was also set aside, because that mode never brings Word forward, so Word's alerts for files in the background were never drawn. Sessions 3b and 3c below are complete default-mode runs.
- `rels-unknown-sibling-control` was inconclusive in session 3b and was observed in session 3c.
- Sessions 3b and 3c were started from a background shell. macOS therefore asked for AppleScript automation authorization for the driver's helper processes, and a person granted each prompt by hand. Every alert was read and attributed, so no outcome depends on this, but later sessions run in the foreground, as the driver's documentation requires.
- No other Word driver ran during sessions 3b (05:02Z–05:18Z) or 3c (05:19Z–05:27Z). Every driver takes the same flock, and the other session's next Word batch began at 05:29Z.

Sessions 4–13 ran in the foreground. Each chunk got one driver run, under `timeout`, with every idle `word_watchdog.sh` paused for that run. Before each single-specimen run, no other `word_pdf` or `word_redline` process was running.

- `s4b` (06:04Z–06:10Z). Mid-run, Word asked for access to `o11.docx`, a file belonging to the other session that no specimen names. The driver granted 33 such prompts, and `rels-part-level-unknown-sibling` timed out on an AppleEvent. That row was set aside and observed alone in `s4c`. Each other `s4b` row is attributed by an alert or a manifest entry naming its staged file.
- `s4d` (06:29Z–06:38Z). Four review Y specimens timed out on AppleEvents or loaded no document in two passes. Each was observed alone from 06:51Z to 06:52Z.
- `s5a` (06:38Z–06:49Z). The run outlived the shell's 600 s foreground limit and was moved to the background, and Word wedged:
    - when the run began, Microsoft Error Reporting showed a report of an earlier Force Quit;
    - later Word returned nothing for three documents in a row, and the driver's recovery asked Word to quit and then ran `pkill`;
    - the run was stopped with SIGINT.

    One alert named `414-xml-trailing-slash-missing` (recovery). Every `s5a` row was still set aside, and all six specimens were observed alone between 06:50Z and 07:03Z. After the stop, the other session's driver took the Word lock, and its watchdog dismissed the same Force Quit report.

- `s7` (07:27Z–07:28Z), `s7b` and `s7c` (07:29Z). Nothing was set aside. No `word_watchdog.sh` was running. Before `s7` and `s7b` no other `word_pdf` or `word_redline` process was running, and `s7c` started ten seconds after `s7b` ended, under the same lock.
- `s8a` (07:47Z–07:48Z), `s8b` (07:48Z), `s9a` (07:50Z), `s9b` (07:51Z), `s10` (07:52Z–07:53Z), `s11` (07:54Z–07:55Z), `s12` (07:58Z–07:59Z) and `s13` (08:04Z). Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running. Each run's preflight found Word not running, launched it, and found no open document (`launched_by_us=True`, `open_documents=0`), so no other session held Word when a run began.

Session 15 ran in the foreground (`s15a` 11:15Z–11:17Z, `s15b` 11:17Z–11:18Z, `s15c` 11:19Z–11:20Z, `s15d` 11:23Z–11:24Z, `s15e` 11:28Z–11:29Z), one driver run per chunk. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running, and before `s15a`, `s15d` and `s15e` no other `word_pdf`, `word_redline` or `osascript` process was running; the only other process naming Word was a Rust test of the other session that reads documents without driving Word. The preflights of `s15a`, `s15d` and `s15e` launched Word and found no open document. Those of `s15b` and `s15c` found a Word process the driver had not launched, with no open document (`launched_by_us=False`, `open_documents=0`); no other session's Word log grew during 11:15Z–11:30Z.

Session 16 ran in the foreground (`s16a` 12:49Z, `s16b` 12:49Z–12:50Z), one driver run per chunk. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running. At 12:49:00Z no `word_pdf`, `word_redline` or `osascript` process was running and Word was not running; the only other process naming Word was a Rust test of the other session that reads documents without driving Word, and that session's newest redline log was last written at 04:57Z. Both preflights launched Word and found no open document (`launched_by_us=True`, `open_documents=0`).

Session 17 ran in the foreground (`s17a` 13:04Z–13:06Z, `s17b` 13:06Z–13:08Z, `s17c` 13:08Z–13:09Z, `s17d` 13:10Z), and session 18 too (`s18a` 13:18Z–13:19Z), one driver run per chunk. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running. Before `s17a`, `s17b`, `s17d` and `s18a` no other `word_pdf`, `word_redline` or `word_watchdog` process was running, and the other session's newest redline log was last written at 04:57Z. The preflight of `s17a` launched Word and found no open document. The Word that `s17b` through `s18a` found (`launched_by_us=False`, `open_documents=0`) started at 13:06:56Z, the second `s17b` started, while its warm-up waited for Word to answer Apple events; it is that run's own Word.

Session 19 ran in the foreground (`s19a` 13:56Z–13:58Z, `s19b` 13:58Z), one driver run per chunk. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running. Before each chunk no other `word_pdf`, `word_redline` or `word_watchdog` process was running, and the other session's newest Word log (`fix013w/ab1721r/wrej.log`) was last written at 13:26:13Z. Both preflights found a Word process the driver had not launched, with no open document (`launched_by_us=False`, `open_documents=0`); it had been running since 13:26:18Z.

Session 20 ran in the foreground (`s20a` 14:28Z, `s20b` 14:29Z, `s20c` 14:30Z, `s20d` 14:30Z), one driver run per chunk of eight. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. No `word_watchdog.sh` was running. Before each chunk, no other `osascript`, `word_pdf` or `word_redline` process was running. The other session was running a review whose notes say it uses no Word automation (`fix013w/rev1716/codex.md`, written 14:27Z). All four preflights found the Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`); it had been running since 13:26Z.

Sessions 21 and 22 ran in the foreground (`s21a` 14:43Z, `s21b` 14:44Z, `s22a` 14:48Z, `s22b` 14:48Z), one driver run per chunk of at most eight. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running. A first guard, at 14:42Z, matched command-line text instead of executables and found two lane agents whose prompts name the driver; it ran nothing, and the guard was changed to match executables before `s21a`. All four preflights found the Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`).

Session 23 ran in the foreground (`s23a` 16:12Z, `s23b` 16:12Z–16:13Z), one driver run per chunk of at most eight. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, and no `word_watchdog.sh` was running. Both preflights found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). The four minimal controls are byte-identical. Their entries are identical to session 22's, and only the ZIP entry timestamps, which JSZip sets at build time, differ.

Session 24 ran in the foreground (`s24a` 18:10Z–18:12Z, `s24b` 18:12Z), one driver run per chunk of at most eight. Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. Both preflights found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). The four minimal controls hold the same entries as session 23's; each chunk's pair is byte-identical, and the two chunks' pairs differ only in ZIP entry timestamps, because each chunk was built by its own run.

Session 25 ran in the foreground (`s25a` 18:37Z), one driver run. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file; the watchdog saw no alert. Before the chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock` (a first guard matched codex's command line, whose prompt text mentions osascript, and was rerun on executable names). The preflight found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). The specimens are the checked-in fixtures, copied byte for byte; no builder was used.

Session 26 ran in the foreground (`s26a` 19:15Z, `s26b` 20:54Z, `s26c` 21:01Z), one driver run per chunk. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file; the watchdog saw no alert. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. All three preflights found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). All three chunks were built at af20d641 with the session 26 builder below.

Session 27 ran in the foreground (`s27a` 22:11Z, `s27b` 22:12Z, `s27c` 22:13Z), one driver run per chunk. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. All three preflights found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). All three chunks were built at 9eb10acb with the session 27 builder below; `s27b` was rebuilt once, before it ran, to add the Strict-URI specimen.

Session 28 ran in the foreground (`s28a` 22:25Z), one driver run. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before the chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. The preflight found a Word process the driver had not launched, with no open document (`word_pid=81589`, `launched_by_us=False`, `open_documents=0`). The chunk was built at 9eb10acb with the session 28 builder below.

Session 29 ran in the foreground (`s29a` 22:57Z, `s29b` 23:01Z), one driver run per chunk. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. No Word process was running either, so the driver launched its own each time (`launched_by_us=True`, `open_documents=0`; `word_pid=72831`, then `85379`). Both chunks were built at 4a5926d3 with the session 29 builder below.

Session 30 ran in the foreground (`s30a` 23:53Z), one driver run. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before the chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`; another session's Word batch had ended at 23:53Z. No Word process was running, so the driver launched its own (`launched_by_us=True`, `open_documents=0`, `word_pid=40732`), and recycled it once after the two refusals (`recovery 1`). The chunk was built at 77d01c46 with the session 30 builder below.

Session 31 ran in the foreground (`s31a` 00:26Z on 2026-10-25), one driver run. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before the chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. No Word process was running, so the driver launched its own (`launched_by_us=True`, `open_documents=0`, `word_pid=39530`). The chunk was built at ceb5c884 with the session 31 builder below.

Session 32 ran in the foreground (`s32a` 01:10Z on 2026-10-25), one driver run. Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before the chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`; another session was running its own converter (`bench docx-to-pdf --converter jubarte-rc`), which does not drive Word. No Word process was running, so the driver launched its own (`launched_by_us=True`, `open_documents=0`, `word_pid=74817`). The chunk was built at 6e3cda3e with the session 32 builder below.

Session 33 ran in the foreground, one driver run per chunk (`s33a` 04:45Z, `s33b` 05:03Z, `s33c` 05:13Z, `s33d` 05:15Z and `s33e` 05:21Z on 2026-10-25). Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`; another session was running its own converters (`bench docx-to-pdf` with `jubarte-rc`, and with `soffice`), which do not drive Word. For `s33a`, `s33c`, `s33d` and `s33e` no Word process was running, so the driver launched its own (`launched_by_us=True`, `open_documents=0`; `word_pid=46992`, `63771`, `70432` and `5565`). `s33b` found the Word `s33a` had left (`launched_by_us=False`, `open_documents=0`, `word_pid=98254`). Every run recycled Word after consecutive refusals (`recovery 1`). In `s33a` and `s33b` Word did not quit within 20 s and the driver ended it with `pkill`; in `s33b` the driver then declined Microsoft Error Reporting's "A Force Quit was performed" notice, which reports that quit. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. `s33a` ran under heavy load (the 15-minute load average read 110.8 at 05:03Z) and took 10 min 16 s, so the harness moved it to the background for its last seconds; three of its items ended in an AppleEvent timeout or with no document and no dialog, and are recorded as inconclusive. `s33c` observed all three shapes again. `s33a` and `s33b` were built at 8b79bc78, the head of #611; `s33c`–`s33e` at 5cd8ada8, #611's merge into `release/0.53.0-rc.2`, whose tree is identical. All five were built with the session 33 builder below.

Session 34 ran in the foreground, one driver run per chunk (`s34a` 06:02Z, `s34b` 06:05Z, `s34c` 06:09Z and `s34d` 06:09Z on 2026-10-25). Nothing was set aside, and every row is attributed by a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, there was no `word.lock`, and no Word process was running, so the driver launched its own each time (`launched_by_us=True`, `open_documents=0`; `word_pid=80094`, `90299`, `9024` and `11548`). `s34a` recycled Word once after three documents in a row came back empty (`recovery 1`, Word quit on request). In `s34b` Word's connection failed ("Connection is invalid") twice around its items 4 and 5, `mce-rels-choice-undeclared-prefix` and `mce-rels-root-mustunderstand`, and the driver relaunched Word; because neither item could be credited with that, `s34c` and `s34d` probed each alone beside a control. In `s34c` Word's process exited after the declined recovery offer and the open error; the driver relaunched it and the control opened clean. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. All four chunks were built at ef5d8107, then the head of layer 131 (`wfv/131-rels-markup-compatibility`: #632's fix on layer 130 at 9ac8d583), with the session 34 builder below; the validator columns are that commit's. Layer 131 was later rebased onto layer 130's head, where #632's fix is c526805a with the same change.

Session 35 ran in the foreground, one driver run per chunk (`s35a` 06:25Z, `s35b` 06:26Z and `s35c` 06:27Z on 2026-10-25). An earlier `s35a` attempt at 06:15Z was set aside without evidence: another session had launched Word at 06:13Z and its `osascript` was running, Word did not answer Apple events within 90 s, and no specimen was opened. Before each recorded chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, there was no `word.lock`, and no Word process was running, so the driver launched its own each time (`launched_by_us=True`; `word_pid=65098`, `68407` and `71367`). In `s35a` the newly launched Word reported one open document (`open_documents=1`, `started_clean=False`), which the driver's preflight closed before the first specimen; `s35b` and `s35c` started clean. `s35b` recycled Word twice (`recovery 1` and `recovery 2`, Word quit on request each time) because the refused specimens open no document; each of its four refused specimens got the same reaction on both passes. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. All three chunks were built at 9ac8d583, then the head of layer 130 (`wfv/130-story-reference-ids`, PR #637), with the session 35 builder below; the validator columns are that commit's.

Session 36 ran in the foreground, one driver run per chunk (`s36a` 07:29Z, `s36b` 07:31Z, `s36c` 07:32Z, `s36d` 07:35Z and `s36e` 07:36Z on 2026-10-25). Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each chunk, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. A Word process (`word_pid=33836`) had been running since 07:03:42Z with no document open; every run used it (`launched_by_us=False`, `open_documents=0`, `started_clean=True`), and no run recycled Word. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. All five chunks were built at dd5a3da2, then the head of layer 131 (`wfv/131-rels-markup-compatibility`), with the session 36 builder below; the validator columns are that commit's. `s36a` and `s36b` were built before `s36c`–`s36e` were added to the builder, and before its verdict helper gained the `try`/`catch` that records `s36c`'s `validate()` throw.

Session 37 ran in the foreground, one driver run per chunk (`s37a` 08:04Z and `s37b` 08:14Z on 2026-10-25). Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each run, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, and there was no `word.lock`. Another session had driven Word until 08:01Z, and again from 08:08Z to 08:12Z. `s37a` used the Word process it left (`word_pid=58661`, running since 08:01:05Z, `launched_by_us=False`, `open_documents=0`, `started_clean=True`); the driver's first attempt at 08:04:04Z refused to run because Word did not answer its document count, and opened nothing. For `s37b` no Word was running, so the driver launched one (`word_pid=94226`, `launched_by_us=True`). During `s37b` the watchdog declined a Microsoft Error Reporting dialog that the driver dated 122 s before the run, a report of the other session's crash, and attributed nothing to it. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. `s37a` was built from #644's lane (840df310 with the fix that became 94d87295) and `s37b` from #645's lane (aed11e4e with the fix that became 76bb5622), with the session 37 builder below. The validator columns were recomputed from the stored specimens at `release/0.53.0-rc.2` (ab2e324f), at the layer 131 head (7cb4041e) and, for `s37b`, at 76bb5622.

Session 38 ran in the foreground, one driver run (`s38a`, 08:54Z on 2026-10-25). Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before the run, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, there was no `word.lock`, and no Word process was running, so the driver launched one (`word_pid=34260`, `launched_by_us=True`, `open_documents=0`, `started_clean=True`). The unselected-Choice row stalled the first pass; the driver recycled Word once and its second pass reproduced the recovery offer and the open error. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. `s38a` was built from #646's lane (aed11e4e with the fix that became 4295889a) with the session 38 builder below. The validator columns were recomputed from the stored specimens at `release/0.53.0-rc.2` (ab2e324f), at the layer 132 head (3788f719) and at 4295889a. Session 37's 76bb5622 is #645's lane commit, which layer 133 carries as 7cb7517c. Both sets of columns were first computed before the stack was rebased onto #664, #666 and #667; recomputed at 3788f719 and 4295889a they match row for row, and so does session 37's 76bb5622 column (`s37b`) at 4295889a.

Session 39 ran in the foreground, one driver run per chunk (`s39a` 09:34Z, `s39b` 09:35Z and `s39c` 09:35Z–09:39Z on 2026-10-25). Nothing was set aside, and every row is attributed by an alert or a manifest entry naming its staged file. Before each run, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, there was no `word.lock`, and no Word process was running, so the driver launched one each time (`word_pid=13188`, `14078` and `14761`, `launched_by_us=True`, `open_documents=0`, `started_clean=True`). In `s39c` Word opened nothing for three documents in a row twice, and the driver recycled it twice; every referenced twin's row carries the unreadable-content offer, and both controls opened clean after the recycles. `~/Library/Logs/DiagnosticReports` holds no Word report from the session. The specimens were built at layer 133 (rebased, source identical to 4295889a) with the session 39 builder below, which follows the shapes of the layer 133 review's own builder. The validator columns were recomputed from the stored specimens at `release/0.53.0-rc.2` (ab2e324f), at the layer 132 head (3788f719) and at 4295889a.

Session 40 ran in the foreground, one driver run per chunk (`s40a` 23:22Z and `s40b` 23:23Z on 2026-10-25). Nothing was set aside, and every row is attributed by a manifest entry naming its staged file; Word showed no alert in either run. Before the runs, no `osascript` executable and no Python process running `word_pdf` or `word_redline` was running, no `word_watchdog.sh` was running, there was no `word.lock` (this session held one for the two runs), and no Word process was running, so the driver launched one each time (`word_pid=54167` and `54433`, `launched_by_us=True`, `open_documents=0`, `started_clean=True`). `~/Library/Logs/DiagnosticReports` holds no Word report from the session. The specimens were built at layer 135 with the session 40 builder below, from source identical to 0e06e03e; the #653 rows are the bytes `repairMissingParaIds` wrote, and release's shape rebuilds that output with the root left as it was. The validator columns were recomputed from the stored specimens at f3bbf27c, the layer before the fixes, and at 0e06e03e.

Session 41 ran in the foreground: 16 driver runs, two per chunk, between 01:16Z and 01:52Z on 2026-10-26. Nothing was set aside. Every rejected row is attributed by an alert naming its staged file, and every clean row by a converted PDF with no alert naming the file.

- **Runs.** The first runs started at 01:16Z (`s41a`), 01:19Z (`s41b`), 01:21Z (`s41c`), 01:23Z (`s41d`), 01:38Z (`s41e`), 01:45Z (`s41f`), 01:47Z (`s41g`) and 01:50Z (`s41h`). The second runs started at 01:29Z, 01:31Z, 01:34Z, 01:36Z, 01:40Z, 01:46Z, 01:48Z and 01:51Z.
- **Bytes.** They were taken with `git show wfv/release-deadline:tests/fixtures/<path>` at c0a244f5 and checked against the SHA-256 the manifest pins. The second-run copies were checked against the first.
- **Lock and other drivers.** This session held `word.lock` for all 16 runs.
    - Before `s41a`'s first run, another session's driver run had just ended (its last log line is at 01:15:56Z), and its list was finished. Its `word_watchdog.sh` logged nothing for that run.
    - That session's next Word jobs started at 01:33Z and waited for this session's driver to exit. Their first driver run began at 01:55:44Z, after this session's last.
    - Before every later run, no Python process running `word_pdf` and no `word_watchdog.sh` was running, checked by executable.
- **Word processes.**
    - `s41a`'s first run used the Word process the other session had left (`word_pid=70629`, `launched_by_us=False`, `open_documents=0`, `started_clean=True`), and 13 runs launched their own (`launched_by_us=True`).
    - Both `s41h` runs used `word_pid=22965`, which no driver of this session launched. Word was started between the end of `s41g`'s second run (01:50:15Z) and `s41h`'s first log line (01:50:33Z, "Word is running but not answering Apple events"), by a process this session could not identify.
    - No other driver wrote a log under `~/temp/T` from 01:50:15Z to 01:52:20Z, and `s41h`'s rows match across both runs and the validator.
- **Recycles.** The driver recycled Word in 13 runs: once in each, and twice in `s41b`'s second run. Each recycle followed a streak where Word opened nothing for two, three or four documents in a row. Every control opened clean.
- **Crash reports.** `~/Library/Logs/DiagnosticReports` holds no Word report from the session.
- **Validator columns.**
    - The fixture columns are `validate()` at c0a244f5 on the same bytes, the verdicts layer 136 pins.
    - The control is session 40's minimal control (`b705a9a7…`), recomputed at c0a244f5.

Session 42 ran in the foreground: four driver runs, two per chunk, between 03:40Z and 03:53Z on 2026-10-26. Nothing was set aside. Every rejected row is attributed by an alert naming its staged file, and every clean row by a converted PDF with no alert naming the file.

- **Runs.** `s42a`'s runs started at 03:40Z and 03:43Z, and `s42b`'s at 03:46Z and 03:50Z.
- **Bytes.** The specimens were built at layer 136 (b6b80433) with the session 42 builder below. The raw-ZIP specimens rebuild byte for byte; the controls are session 40's minimal control (`b705a9a7…`), copied, not rebuilt. `compare.py` checked every file Word was given, in both runs, against the SHA-256 recorded at build time.
- **Lock and other drivers.** This session held `word.lock` for all four runs. Before the first, no `osascript` executable, no Python process running `word_pdf` or `word_redline`, no `word_watchdog.sh` and no Word process was running; before each later run, no such driver and no watchdog was running, checked by executable. Another session's driver started at 03:53:28Z, 21 s after this session's last run ended (03:53:07Z).
- **Word processes.** Every run launched its own Word (`word_pid=33335`, `36505`, `39049` and `43683`, `launched_by_us=True`, `open_documents=0`, `started_clean=True`).
- **Recycles.** The driver restarted Word once in each of three runs (`s42a`'s second and both of `s42b`'s), each after Word opened nothing for one to three documents in a row. `s42a`'s second run had first closed every document once and carried on with the same Word. Every control opened clean.
- **Crash reports.** `~/Library/Logs/DiagnosticReports` holds no Word report from the session.
- **Validator columns.** `validate()` at b6b80433 on the same bytes, recorded by the builder.

Session 43 ran in the foreground: two driver runs of one chunk, at 06:25:10Z and 06:25:42Z on 2026-10-26, each over in under 20 s. Nothing was set aside. The rejected row is attributed by alerts naming its staged file, and the clean row by a converted PDF with no alert naming the file.

- **Bytes.** The specimen and the control are copies of session 42's `629-empty-segment` (`3292bc6f…`) and session 40's minimal control (`b705a9a7…`); the session 43 builder below refuses any other bytes. `compare.py` checked both files, in both runs, against those SHA-256s.
- **Lock and other drivers.** This session held `word.lock` for both runs. Before the first, no `osascript` executable, no Python process running `word_pdf` or `word_redline`, no `word_watchdog.sh` and no Word process was running; before the second, no such driver and no watchdog was running, checked by executable.
- **Word processes.** Each run launched its own Word (`word_pid=36286` and `36691`, `launched_by_us=True`, `open_documents=0`, `started_clean=True`). Neither run restarted Word.
- **Crash reports.** `~/Library/Logs/DiagnosticReports` holds no Word report from the session.
- **Validator columns.** `validate()` at 6473f54b on the same bytes, recorded by the builder.

Session 44 ran in the foreground: six driver runs, two per chunk, between 06:56Z and 07:01Z on 2026-10-26, each over in under 30 s. Nothing was set aside. The rejected row is attributed by alerts naming its staged file, and every clean row by a converted PDF with no alert naming the file.

- **Bytes.** The specimens were built at layer 138 (37a691ce) with the session 44 builder below. `chart-outside-word-mixed-reach-no-sidecar` is s37b's file, which the builder refuses unless its SHA-256 starts `d9fcab69f2cdbbb8`. `compare.py` checked every file, in both runs, against the builder's SHA-256s, and the session 44 rows of `tests/relationship-sidecar.integration.test.ts` rebuild each other probed specimen's parts exactly (13 of 13, compared part by part).
- **Lock and other drivers.** This session held `word.lock` for every run and, before each, checked by executable that no `word_pdf` or `word_redline` driver and no `word_watchdog.sh` was running. The second `s44a` run was refused once, because another session's `word_pdf.py` was driving Word over its own folder; it started after that driver exited.
- **Word processes.** Each run launched its own Word (`word_pid` 89934, 94726, 6247, 11980, 19275 and 19459; `launched_by_us=True`, `open_documents=0`, `started_clean=True`). In each `s44a` run the driver restarted Word once (`recovery 1: … Word quit on request`) after the referenced chart opened nothing, retried that file, and failed it after the second pass.
- **Crash reports.** `~/Library/Logs/DiagnosticReports` holds no Word report.
- **Validator columns.** `validate()` at 37a691ce on the same bytes, recorded by the builder.

Sessions 4–6 observed `main-relationship-missing` (#380), the #414 `PartName`s with `application/xml`, an escape in a folder segment (#408), a part-level relationships part (#433) and an unreferenced malformed `customXml/item9.xml` (#437). Still to be observed:

- A part Word reads, such as the main part, whose local-header name differs from its central-directory name (#411, review Y).
- A percent-escaped `PartName` that names a stored part (#451). Session 8 observed `%E9` for a missing part.
- Markup Compatibility elements or attributes in `[Content_Types].xml` (#459).
- An empty `ContentType` on an `Override` other than the main document's, or on a `Default` (#581). Session 22 observed the main document's `Override` only.
- An inexact type on the settings, fontTable, webSettings or numbering part a reached glossary relates (#579). Session 21 observed the styles part, and session 22 a header the glossary references.
- A story part declared with a foreign type other than the header/footer swap (#600): a footer typed `…styles+xml`, comments, footnotes or endnotes typed with each other's types, or a non-WordprocessingML type such as `image/png`. Session 24 observed only the swap.
- A part reached by an unused `header` relationship and a read `footer` relationship, declared with the header type (#600, #593).
- The generic Default on the settings, fontTable, webSettings or numbering part a reached glossary relates, or on a story it references (#601). Session 24 observed the glossary's styles part.

## Observations

### Session 1: 02:18Z–02:26Z, validator at 199c2d5b

| Specimen                                 | Issue   | SHA-256 (first 16) | Word           | word-valid at probe time                                                                                                    | strict at probe time |
| ---------------------------------------- | ------- | ------------------ | -------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `control-minimal`                        | control | `e3fd9a9607c643b1` | clean-open     | valid                                                                                                                       | valid                |
| `388-rels-zero-byte`                     | #388    | `518a110444455811` | repair-warning | valid                                                                                                                       | invalid              |
| `388-rels-truncated`                     | #388    | `a85ad66282671910` | repair-warning | valid                                                                                                                       | invalid              |
| `388-rels-undeclared-prefix`             | #388    | `19383610c2a9f89a` | repair-warning | valid                                                                                                                       | invalid              |
| `392-WORD-folder-clean`                  | #392    | `36d4625db191d3e9` | clean-open     | valid                                                                                                                       | valid                |
| `392-WORD-folder-malformed-main`         | #392    | `b5c3d2178d4696be` | open-error     | invalid (`xml-undeclared-prefix@WORD/document.xml`, `xml-syntax@WORD/document.xml`)                                         | invalid              |
| `392-word-folder-malformed-main-control` | #392    | `95d4f0bfb82a2c4a` | open-error     | invalid (`xml-undeclared-prefix@word/document.xml`, `xml-syntax@word/document.xml`)                                         | invalid              |
| `396-CT-upper-clean`                     | #396    | `744bbb14ad7f0f3e` | clean-open     | valid                                                                                                                       | valid                |
| `396-CT-upper-invalid-type`              | #396    | `ec74a991d4b8b9dc` | clean-open     | invalid (`word-content-type-invalid@[CONTENT_TYPES].XML`)                                                                   | invalid              |
| `396-CT-exact-invalid-type-control`      | #396    | `9857e3aaebaa53d7` | clean-open     | invalid (`word-content-type-invalid@[Content_Types].xml`)                                                                   | invalid              |
| `396-CT-upper-malformed`                 | #396    | `949e38e644ebd7db` | repair-warning | invalid (`xml-syntax@[CONTENT_TYPES].XML`)                                                                                  | invalid              |
| `397-encoding-unknown`                   | #397    | `a45331da8b2129ea` | open-error     | valid                                                                                                                       | invalid              |
| `397-encoding-windows-1252-control`      | #397    | `0e8165d11d1898b5` | clean-open     | valid                                                                                                                       | valid                |
| `351-dup-case-identical`                 | #351    | `48a8b62b9c83535d` | repair-warning | invalid (`package-extract-failed@-`)                                                                                        | invalid              |
| `351-dup-case-lower-good-upper-bad`      | #351    | `2d58ed5a3241a634` | repair-warning | invalid (`package-extract-failed@-`)                                                                                        | invalid              |
| `351-dup-case-upper-bad-first`           | #351    | `8ef60be49ff4ac55` | repair-warning | invalid (`package-extract-failed@-`)                                                                                        | invalid              |
| `351-dup-stream-good-then-bad`           | #351    | `970eca474f9eba1c` | repair-warning | invalid (`package-extract-failed@-`)                                                                                        | invalid              |
| `351-dup-stream-bad-then-good`           | #351    | `b503d9e06055091e` | repair-warning | invalid (`package-extract-failed@-`)                                                                                        | invalid              |
| `398-RELS-sidecar-clean`                 | #398    | `ac61b47790dc028b` | clean-open     | valid                                                                                                                       | valid                |
| `398-dup-theme-control`                  | #398    | `52b18dea69dafe56` | repair-warning | invalid (`word-duplicate-theme-relationship@word/_rels/document.xml.rels`)                                                  | invalid              |
| `398-dup-theme-RELS`                     | #398    | `f1a5a570c9effd78` | repair-warning | invalid (`word-duplicate-theme-relationship@word/_rels/document.xml.RELS`, `word-hyperlink-relationship@word/document.xml`) | invalid              |
| `cti-override-existing-styles`           | #401    | `dde1b233d9672e0f` | repair-warning | invalid (`word-content-type-invalid@[Content_Types].xml`)                                                                   | invalid              |
| `cti-override-existing-main`             | #401    | `bded55854c3edf59` | repair-warning | invalid (`word-content-type-invalid@[Content_Types].xml`)                                                                   | invalid              |
| `cti-override-existing-core`             | #401    | `f4081445c08647f1` | open-error     | invalid (`word-content-type-invalid@[Content_Types].xml`)                                                                   | invalid              |
| `cti-override-existing-core-control`     | #401    | `86df51ceafbcb5ba` | clean-open     | valid                                                                                                                       | valid                |
| `cti-default-unused-extension`           | #401    | `d19b131b7b46dbba` | clean-open     | invalid (`word-content-type-invalid@[Content_Types].xml`)                                                                   | invalid              |
| `351-dup-escape-identical`               | #351    | `f5cd33350d5e730e` | repair-warning | valid                                                                                                                       | invalid              |
| `351-dup-backslash-identical`            | #351    | `348701aaaa331f41` | repair-warning | valid                                                                                                                       | valid                |

### Session 2: 03:10Z–03:19Z, validator at ad072db8

| Specimen                             | Issue | SHA-256 (first 16) | Word           | word-valid at probe time                                                                            | strict at probe time |
| ------------------------------------ | ----- | ------------------ | -------------- | --------------------------------------------------------------------------------------------------- | -------------------- |
| `351-escape-only-styles`             | #351  | `ca196e7ef4a292f2` | repair-warning | valid                                                                                               | valid                |
| `351-backslash-only-main`            | #351  | `869f616f1ba1640e` | clean-open     | valid                                                                                               | valid                |
| `398-hyperlink-rels-control`         | #398  | `21f622f77bf187c2` | clean-open     | valid                                                                                               | valid                |
| `398-hyperlink-%72els`               | #402  | `48a74a89fdd0177e` | repair-warning | invalid (`rels-missing-sidecar@word/document.xml`, `word-hyperlink-relationship@word/document.xml`) | invalid              |
| `398-hyperlink-RELS`                 | #398  | `440b780d13f48f40` | clean-open     | invalid (`word-hyperlink-relationship@word/document.xml`)                                           | invalid              |
| `397-encoding-unknown-styles`        | #397  | `d2c61a613863872e` | repair-warning | invalid (`xml-encoding@word/styles.xml`)                                                            | invalid              |
| `397-encoding-unknown-content-types` | #397  | `a2be2959ad591d9a` | repair-warning | invalid (`xml-encoding@[Content_Types].xml`)                                                        | invalid              |
| `397-encoding-unknown-package-rels`  | #397  | `c8a06454f5c52111` | repair-warning | invalid (`xml-encoding@_rels/.rels`)                                                                | invalid              |
| `397-encoding-unknown-core`          | #397  | `bde4363f2fed0946` | repair-warning | valid                                                                                               | invalid              |
| `397-invalid-utf8-bytes`             | #397  | `87b043160608a0aa` | open-error     | invalid (`xml-encoding@word/document.xml`)                                                          | invalid              |
| `esc-unreferenced-extra-item`        | #408  | `02392f4064145df1` | repair-warning | valid                                                                                               | invalid              |
| `esc-styles-missing-control`         | #408  | `79dddb1d4ffcd1ca` | clean-open     | valid                                                                                               | invalid              |
| `esc-only-main`                      | #408  | `845abca15ef137fe` | repair-warning | valid                                                                                               | valid                |
| `docprops-core-truncated`            | #409  | `0f729853110d309f` | repair-warning | valid                                                                                               | invalid              |
| `docprops-app-control`               | #409  | `727b58abd042452e` | clean-open     | valid                                                                                               | valid                |

Full hashes, dialog text and observation times are in the JSONL record of each probe, reproduced below.

<details><summary>Raw records</summary>

```jsonl
{"name": "control-minimal", "sha256": "e3fd9a9607c643b1615001a916501be367de53faeb4fd925ea38a4e8c034555b", "observedAt": "2026-10-24T02:18:56.522Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-e3fd9a9607c6-22ee5d2f.docx; buttons=missing value,missing value,missing value"}
{"name": "388-rels-zero-byte", "sha256": "518a110444455811628385302e5c5f69036f8543327108eda929ac46bdccdcc8", "observedAt": "2026-10-24T02:19:10.007Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-518a11044445-3a7272c0.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "388-rels-truncated", "sha256": "a85ad662826719107f763185b905b4609e0e03b65393a0f1fc3ad24d955099c9", "observedAt": "2026-10-24T02:19:13.170Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-a85ad6628267-6e2605ed.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "388-rels-undeclared-prefix", "sha256": "19383610c2a9f89af29cd2ce549f38d09c2a3cec4510ab6111aeb97492230cbb", "observedAt": "2026-10-24T02:19:16.391Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-19383610c2a9-39293b8c.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "392-WORD-folder-clean", "sha256": "36d4625db191d3e9d58ea1d2f108c3829bb1120e415137574bf105a6d642dfb0", "observedAt": "2026-10-24T02:19:19.571Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-36d4625db191-17e063f1.docx; buttons=missing value,missing value,missing value"}
{"name": "392-WORD-folder-malformed-main", "sha256": "b5c3d2178d4696be642c02a63acc76ddbecbb89e5949fff78d77d6e34f077b89", "observedAt": "2026-10-24T02:19:25.387Z", "outcome": "open-error", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word experienced an error trying to open the file.; buttons=OK"}
{"name": "392-word-folder-malformed-main-control", "sha256": "95d4f0bfb82a2c4ad256fd0692fef37730d9e00601bc8df2e6c50bb758913072", "observedAt": "2026-10-24T02:19:27.963Z", "outcome": "open-error", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word experienced an error trying to open the file.; buttons=OK"}
{"name": "396-CT-upper-clean", "sha256": "744bbb14ad7f0f3ea38903283a49203448d176fb81e7a42fb4f3e5923200b2d2", "observedAt": "2026-10-24T02:19:30.409Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-744bbb14ad7f-533bc5b2.docx; buttons=missing value,missing value,missing value"}
{"name": "396-CT-upper-invalid-type", "sha256": "ec74a991d4b8b9dcd0e18603f3fe10130f4e05058985046034fd3757fb18abc6", "observedAt": "2026-10-24T02:19:36.354Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-ec74a991d4b8-68a1da7f.docx; buttons=missing value,missing value,missing value"}
{"name": "396-CT-exact-invalid-type-control", "sha256": "9857e3aaebaa53d7938dd1a048d43965b628faa6a40604a0319dc4baf1892840", "observedAt": "2026-10-24T02:19:42.537Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-9857e3aaebaa-48b7cbb6.docx; buttons=missing value,missing value,missing value"}
{"name": "396-CT-upper-malformed", "sha256": "949e38e644ebd7dbae84d399c5682ad07adea9feaf661f4f51e206782d3e4705", "observedAt": "2026-10-24T02:19:48.322Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-949e38e644eb-491711fa.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "397-encoding-unknown", "sha256": "a45331da8b2129ea843e382a493a38605597921880738ba558e9f12fce5ce0aa", "observedAt": "2026-10-24T02:19:51.391Z", "outcome": "open-error", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word experienced an error trying to open the file.; buttons=OK"}
{"name": "397-encoding-windows-1252-control", "sha256": "0e8165d11d1898b5d286c31c832235942657751da8b9f4444aa89193c056fb8b", "observedAt": "2026-10-24T02:19:53.893Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-0e8165d11d18-5f5e06b4.docx; buttons=missing value,missing value,missing value"}
{"name": "351-dup-case-identical", "sha256": "48a8b62b9c83535d2d93e2ef9b0bcbc7f40f703f9bd63c9dbabb534b21e343e9", "observedAt": "2026-10-24T02:20:00.197Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-48a8b62b9c83-3ba31e8f.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-dup-case-lower-good-upper-bad", "sha256": "2d58ed5a3241a6341c59340a0723c64c00508566c3a7bc6b56165f26383144ca", "observedAt": "2026-10-24T02:20:04.079Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-2d58ed5a3241-15e1301a.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-dup-case-upper-bad-first", "sha256": "8ef60be49ff4ac5507c1be56e26e9312f2c3965103b4a933084f4a419526a387", "observedAt": "2026-10-24T02:20:07.779Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-8ef60be49ff4-1ee9161e.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-dup-stream-good-then-bad", "sha256": "970eca474f9eba1c30fc10fb4343195616cbfc0863c8e7247a3752ea7a89b518", "observedAt": "2026-10-24T02:20:11.571Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-970eca474f9e-69aa90bc.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-dup-stream-bad-then-good", "sha256": "b503d9e06055091e24edec6fe109722fbc26b37eca71911b727fa5199eb0b294", "observedAt": "2026-10-24T02:20:15.230Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-b503d9e06055-4b6e42d7.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "398-RELS-sidecar-clean", "sha256": "ac61b47790dc028bfdd35606ee0ed593c843c98df57c107a2ca626d201743928", "observedAt": "2026-10-24T02:20:18.973Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-ac61b47790dc-a167f9e.docx; buttons=missing value,missing value,missing value"}
{"name": "398-dup-theme-control", "sha256": "52b18dea69dafe56f1242778155d03e1dc419395f21dac99436ff06fc3305758", "observedAt": "2026-10-24T02:20:24.995Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-52b18dea69da-315ee282.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "398-dup-theme-RELS", "sha256": "f1a5a570c9effd789dd70cf7264b12bed75d4b930325b156f74a625d34617dd0", "observedAt": "2026-10-24T02:20:28.959Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-f1a5a570c9ef-d43130e.docx. Do you want to recover the contents of this document? If you trust the so; buttons=Yes,No"}
{"name": "cti-override-existing-styles", "sha256": "dde1b233d9672e0f4038cd6439d2109cc2daf31e737a634c628681624a3d9366", "observedAt": "2026-10-24T02:25:27.343Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-dde1b233d967-152ec719.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "cti-override-existing-main", "sha256": "bded55854c3edf59deb21a1e9942d9a901c7585d2101bae26e5673cf04d6d465", "observedAt": "2026-10-24T02:25:32.196Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-bded55854c3e-2f5ded2d.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "cti-override-existing-core", "sha256": "f4081445c08647f1ffa572eb8b305e8bbf656df9505728bc795851c8a0337426", "observedAt": "2026-10-24T02:25:36.391Z", "outcome": "open-error", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word experienced an error trying to open the file.; buttons=OK"}
{"name": "cti-override-existing-core-control", "sha256": "86df51ceafbcb5ba7dbbe52523c8dfd47749e105f22efe99c62e0e4daf152b5a", "observedAt": "2026-10-24T02:25:39.665Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-86df51ceafbc-1154a840.docx; buttons=missing value,missing value,missing value"}
{"name": "cti-default-unused-extension", "sha256": "d19b131b7b46dbba48f21f4997752bfcbc97722bfde8b714b4f8f2e9d7cf4374", "observedAt": "2026-10-24T02:25:46.833Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-d19b131b7b46-75ea9926.docx; buttons=missing value,missing value,missing value"}
{"name": "351-dup-escape-identical", "sha256": "f5cd33350d5e730e8d7729493407a69834a98a8cc5ea78d258700a462ec1234c", "observedAt": "2026-10-24T02:25:53.635Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-f5cd33350d5e-1ee1b408.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-dup-backslash-identical", "sha256": "348701aaaa331f414752bb12024e1227f17c0ae9695c15b0785f91b935d1881b", "observedAt": "2026-10-24T02:25:58.711Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-348701aaaa33-46da418.docx. Do you want to recover the contents of this document? If you trust the so; buttons=Yes,No"}
{"name": "351-escape-only-styles", "sha256": "ca196e7ef4a292f215eec905800c44a95308695b4c846da3c8de202bc42961d3", "observedAt": "2026-10-24T03:10:04.556Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-ca196e7ef4a2-340c7c4b.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "351-backslash-only-main", "sha256": "869f616f1ba1640e7d87b83017fcfec7e25afc8fc8f584031e1c38bc6c3f6d38", "observedAt": "2026-10-24T03:10:12.763Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-869f616f1ba1-74030a55.docx; buttons=missing value,missing value,missing value"}
{"name": "398-hyperlink-rels-control", "sha256": "21f622f77bf187c2ed548011da2c47aa1112bdd346fd4c65952818a1543b078e", "observedAt": "2026-10-24T03:10:20.131Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-21f622f77bf1-60b154d8.docx; buttons=missing value,missing value,missing value"}
{"name": "398-hyperlink-%72els", "sha256": "48a74a89fdd0177e2a178168e47928058da5f14e6c36c431e417ff6be40ecb02", "observedAt": "2026-10-24T03:10:27.011Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-48a74a89fdd0-29d9260f.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "398-hyperlink-RELS", "sha256": "440b780d13f48f405af64eb498d30fba0cb997425bc837923216316657114499", "observedAt": "2026-10-24T03:10:30.750Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-440b780d13f4-76dd9f42.docx; buttons=missing value,missing value,missing value"}
{"name": "397-encoding-unknown-styles", "sha256": "d2c61a613863872e925e6ad9bff68fa6504b40dacf914d14d022da8cc899dd91", "observedAt": "2026-10-24T03:10:38.075Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-d2c61a613863-25dfa1c5.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "397-encoding-unknown-content-types", "sha256": "a2be2959ad591d9a05198194d558d46633ab45fc3cec5255e96aa0e3a62e21d6", "observedAt": "2026-10-24T03:10:41.809Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-a2be2959ad59-5c626fc1.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "397-encoding-unknown-package-rels", "sha256": "c8a06454f5c52111b62db510785a73580b46cde2901bfa35cfaade2c3d563239", "observedAt": "2026-10-24T03:10:45.804Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-c8a06454f5c5-7c6602f9.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "397-encoding-unknown-core", "sha256": "bde4363f2fed0946d3c27b124d6b8c4d73332c190f269345a0ebecac541168a6", "observedAt": "2026-10-24T03:10:49.836Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-bde4363f2fed-2869ea96.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "397-invalid-utf8-bytes", "sha256": "87b043160608a0aaab2944629c3bb96f204ab7b1e7f923f82066851eb02f037a", "observedAt": "2026-10-24T03:10:53.694Z", "outcome": "open-error", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word experienced an error trying to open the file.; buttons=OK"}
{"name": "esc-unreferenced-extra-item", "sha256": "02392f4064145df1ab5015e564bed05841e805071ce9a306cca94f71cc975c56", "observedAt": "2026-10-24T03:11:55.380Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-02392f406414-5510bdc.docx. Do you want to recover the contents of this document? If you trust the so; buttons=Yes,No"}
{"name": "esc-styles-missing-control", "sha256": "79dddb1d4ffcd1caf0f6238942fcc5af4f6a5f9d97e5499fd3b064f78e66a818", "observedAt": "2026-10-24T03:12:04.007Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-79dddb1d4ffc-4ce497ad.docx; buttons=missing value,missing value,missing value"}
{"name": "esc-only-main", "sha256": "845abca15ef137feff7301f1809b31a5a63f03c50854d6404d5e0a90236d856f", "observedAt": "2026-10-24T03:12:13.526Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-845abca15ef1-6a85ef09.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "docprops-core-truncated", "sha256": "0f729853110d309f0857d4a4784ff7d98f9d23f1b581bf1526c56b536119e94b", "observedAt": "2026-10-24T03:19:10.366Z", "outcome": "repair-warning", "details": "processAlive=true; documents=0; dialog=Microsoft Word Word found unreadable content in docx-verify-0f729853110d-654190a6.docx. Do you want to recover the contents of this document? If you trust the s; buttons=Yes,No"}
{"name": "docprops-app-control", "sha256": "727b58abd042452e1587525f3932f401bfc4b5f9160d526779718b1d31a0b436", "observedAt": "2026-10-24T03:19:22.290Z", "outcome": "clean-open", "details": "processAlive=true; documents=1; names=docx-verify-727b58abd042-4fd3d74d.docx; buttons=missing value,missing value,missing value"}
```

</details>

### Session 3b: 05:02Z–05:18Z, validator columns at ab7f311d

The first eight rows rebuild session 1 and 2 specimens to calibrate the driver against `verifyInWord`: `control-minimal`, `397-encoding-windows-1252-control`, `351-dup-case-identical`, `cti-override-existing-core-control`, `398-hyperlink-RELS`, `docprops-core-truncated`, `esc-unreferenced-extra-item` and `397-encoding-unknown-core`. All eight reproduce their earlier outcomes. `s3-control-minimal-start` and `s3-control-minimal-end` bracket the new specimens.

| Specimen                              | Issue      | SHA-256 (first 16) | Word           | word-valid at ab7f311d                                                                                                             | strict at ab7f311d                                                                                                                 |
| ------------------------------------- | ---------- | ------------------ | -------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `control-minimal`                     | control    | `0160dfc1db4c5ce1` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `397-encoding-windows-1252-control`   | #397       | `3ccb84b7f1be0b88` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `351-dup-case-identical`              | #351       | `4400bc4cd6b8d23a` | repair-warning | invalid (`opc-equivalent-part-names@word/document.xml`, `package-extract-failed`)                                                  | invalid (`opc-equivalent-part-names@word/document.xml`, `package-extract-failed`)                                                  |
| `cti-override-existing-core-control`  | #401       | `ae55ebebdd97a971` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `398-hyperlink-RELS`                  | #398       | `18b773c0d5d7ec6f` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `docprops-core-truncated`             | #409       | `c8eb3d968d217f0c` | repair-warning | valid                                                                                                                              | invalid (`xml-syntax@docProps/core.xml`, `xml-undeclared-prefix@docProps/core.xml`)                                                |
| `esc-unreferenced-extra-item`         | #408       | `d8ad7b6fa1e05937` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/%78tra.xml`)                                                                       | invalid (`rels-unreferenced@word/%78tra.xml`, `opc-part-name-escaped-unreserved@word/%78tra.xml`)                                  |
| `397-encoding-unknown-core`           | #397       | `031ee748acdee96d` | repair-warning | valid                                                                                                                              | invalid (`xml-encoding@docProps/core.xml`)                                                                                         |
| `s3-control-minimal-start`            | control    | `3cdc3192bc053374` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `docprops-app-truncated`              | #409       | `96ef7c3a11c2d06a` | repair-warning | valid                                                                                                                              | invalid (`xml-syntax@docProps/app.xml`)                                                                                            |
| `docprops-app-encoding-unknown`       | #409       | `3a3d526f35194415` | repair-warning | valid                                                                                                                              | invalid (`xml-encoding@docProps/app.xml`)                                                                                          |
| `docprops-app-undeclared-prefix`      | #409       | `ee29efbb9af0ee63` | repair-warning | valid                                                                                                                              | invalid (`xml-undeclared-prefix@docProps/app.xml`)                                                                                 |
| `docprops-core-undeclared-prefix`     | #409       | `9692d5b7434cea96` | repair-warning | valid                                                                                                                              | invalid (`xml-undeclared-prefix@docProps/core.xml`)                                                                                |
| `docprops-custom-control`             | #409       | `a82099eacbd6b8ed` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `docprops-custom-truncated`           | #409       | `2619e0980a11bbf6` | repair-warning | valid                                                                                                                              | invalid (`xml-syntax@docProps/custom.xml`)                                                                                         |
| `docprops-custom-undeclared-prefix`   | #409       | `de4ca7ce3c73f670` | repair-warning | valid                                                                                                                              | invalid (`xml-undeclared-prefix@docProps/custom.xml`)                                                                              |
| `docprops-custom-encoding-unknown`    | #409       | `1d03dad3ff19c572` | repair-warning | valid                                                                                                                              | invalid (`xml-encoding@docProps/custom.xml`)                                                                                       |
| `410-macintosh`                       | #410       | `9f5a2e272d2e34cb` | open-error     | invalid (`xml-encoding@word/document.xml`)                                                                                         | invalid (`xml-encoding@word/document.xml`)                                                                                         |
| `410-x-mac-cyrillic`                  | #410       | `81d8f59f16ff8e5d` | open-error     | invalid (`xml-encoding@word/document.xml`)                                                                                         | invalid (`xml-encoding@word/document.xml`)                                                                                         |
| `410-IBM866`                          | #410       | `b48036e2d2f7d93c` | open-error     | invalid (`xml-encoding@word/document.xml`)                                                                                         | invalid (`xml-encoding@word/document.xml`)                                                                                         |
| `410-UTF-7`                           | #410       | `6bf6863458ce8038` | open-error     | invalid (`xml-encoding@word/document.xml`)                                                                                         | invalid (`xml-encoding@word/document.xml`)                                                                                         |
| `410-windows-1252-nonascii-control`   | #410       | `e004e8ebb0082fbd` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `411-identical-valid-valid`           | #411       | `ea01967dbdd15786` | repair-warning | invalid (`opc-equivalent-part-names@word/document.xml`)                                                                            | invalid (`opc-equivalent-part-names@word/document.xml`)                                                                            |
| `411-identical-valid-then-malformed`  | #411       | `3ac694002959888c` | repair-warning | invalid (`xml-undeclared-prefix@word/document.xml`, `xml-syntax@word/document.xml`, `opc-equivalent-part-names@word/document.xml`) | invalid (`xml-undeclared-prefix@word/document.xml`, `xml-syntax@word/document.xml`, `opc-equivalent-part-names@word/document.xml`) |
| `411-identical-malformed-then-valid`  | #411       | `4ada736ae140496e` | repair-warning | invalid (`opc-equivalent-part-names@word/document.xml`)                                                                            | invalid (`opc-equivalent-part-names@word/document.xml`)                                                                            |
| `411-dotdot-unreferenced-item`        | #411       | `97f752f1b03e1749` | repair-warning | invalid (`package-extract-failed`)                                                                                                 | invalid (`package-extract-failed`)                                                                                                 |
| `411-dotdot-then-plain-styles`        | #411       | `e68121f4cf107657` | repair-warning | invalid (`package-extract-failed`)                                                                                                 | invalid (`package-extract-failed`)                                                                                                 |
| `414-styles-override-removed-control` | #432       | `e0595fa4e2e464ec` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `414-styles-override-dotdot`          | #414       | `1fa751332e19b8f0` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `414-styles-override-query`           | #414       | `75810dc3e308696a` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `414-styles-override-fragment`        | #414       | `7a16f99036a62688` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `414-styles-override-backslash`       | #414       | `4e5e85d63f2ee9c3` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `414-invalid-x-dotdot-main`           | #414       | `f7bae552bbd4fd8a` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                       |
| `414-invalid-x-query-main`            | #414       | `0ceb5371ecc1714b` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                       |
| `414-invalid-x-fragment-main`         | #414       | `00fb33975b0027c9` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                       |
| `414-invalid-x-backslash-main`        | #414       | `f6451c46a8323938` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                       |
| `dupdecl-default-identical`           | #431       | `222d7ee2fc43b1f6` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `dupdecl-default-case`                | #431       | `fe596b4f8f32a55c` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `dupdecl-override-identical`          | #431       | `92c289efb80c1b41` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `dupdecl-override-conflicting`        | #431       | `1fe83fb76ef60ec2` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `dupdecl-override-case`               | #431       | `2f9f7277561b364b` | repair-warning | valid                                                                                                                              | valid                                                                                                                              |
| `esc-plain-unreferenced-control`      | #408       | `6e63642feef861ab` | clean-open     | valid                                                                                                                              | invalid (`rels-unreferenced@word/xtra.xml`)                                                                                        |
| `esc-%41-upper-letter`                | #408       | `fae72ee8b638fa8a` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%41.xml`)                                                                         | invalid (`rels-unreferenced@word/x%41.xml`, `opc-part-name-escaped-unreserved@word/x%41.xml`)                                      |
| `esc-%30-digit`                       | #408       | `17d763961bc3f58c` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%30.xml`)                                                                         | invalid (`rels-unreferenced@word/x%30.xml`, `opc-part-name-escaped-unreserved@word/x%30.xml`)                                      |
| `esc-%2D-hyphen`                      | #408       | `84a0e0f1843139fd` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%2D.xml`)                                                                         | invalid (`rels-unreferenced@word/x%2D.xml`, `opc-part-name-escaped-unreserved@word/x%2D.xml`)                                      |
| `esc-%2d-hyphen-lowerhex`             | #408       | `37529d0e79b352aa` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%2d.xml`)                                                                         | invalid (`rels-unreferenced@word/x%2d.xml`, `opc-part-name-escaped-unreserved@word/x%2d.xml`)                                      |
| `esc-%2E-period`                      | #408       | `fcbdbbf79faa0bcd` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%2E.xml`)                                                                         | invalid (`rels-unreferenced@word/x%2E.xml`, `opc-part-name-escaped-unreserved@word/x%2E.xml`)                                      |
| `esc-%5F-underscore`                  | #408       | `7d0278c4bf9fd3fa` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%5F.xml`)                                                                         | invalid (`rels-unreferenced@word/x%5F.xml`, `opc-part-name-escaped-unreserved@word/x%5F.xml`)                                      |
| `esc-%7E-tilde`                       | #408       | `4436f009f2500d57` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/x%7E.xml`)                                                                         | invalid (`rels-unreferenced@word/x%7E.xml`, `opc-part-name-escaped-unreserved@word/x%7E.xml`)                                      |
| `esc-%20-space-control`               | #408       | `c7598087941b0c35` | clean-open     | valid                                                                                                                              | invalid (`rels-unreferenced@word/x%20y.xml`)                                                                                       |
| `s3-control-minimal-end`              | control    | `00d28798c1f66dc7` | clean-open     | valid                                                                                                                              | valid                                                                                                                              |
| `rels-main-nested-in-unknown-element` | #433, #434 | `176e6d8f133812b3` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@_rels/.rels`, `xsd-error@_rels/.rels`)                                                                       |
| `rels-root-not-relationships`         | #433       | `1a5c659713cf7f9b` | repair-warning | valid                                                                                                                              | invalid (`xsd-summary@_rels/.rels`, `xsd-error@_rels/.rels`)                                                                       |
| `rels-unknown-sibling-control`        | #433       | `27cb9b0032c7b10c` | inconclusive   | valid                                                                                                                              | invalid (`xsd-summary@_rels/.rels`, `xsd-error@_rels/.rels`)                                                                       |

### Session 3c: 05:19Z–05:27Z, validator columns at ab7f311d

| Specimen                                         | Issue      | SHA-256 (first 16) | Word           | word-valid at ab7f311d                                                      | strict at ab7f311d                                                                                                          |
| ------------------------------------------------ | ---------- | ------------------ | -------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `s3c-control-minimal`                            | control    | `1a414a1109291a18` | clean-open     | valid                                                                       | valid                                                                                                                       |
| `ct-stream-missing-control`                      | #435       | `a4c6ecaf2f422b09` | repair-warning | valid                                                                       | invalid (`ct-missing`)                                                                                                      |
| `ct-stream-escaped-only`                         | #408, #435 | `42d70cff0d0d0e1a` | repair-warning | invalid (`opc-part-name-escaped-unreserved@[Content_Types].%78ml`)          | invalid (`rels-unreferenced@[Content_Types].%78ml`, `ct-missing`, `opc-part-name-escaped-unreserved@[Content_Types].%78ml`) |
| `ct-stream-escaped-extra`                        | #408       | `898d49c3184b8458` | repair-warning | invalid (`opc-part-name-escaped-unreserved@[Content_Types].%78ml`)          | invalid (`rels-unreferenced@[Content_Types].%78ml`, `opc-part-name-escaped-unreserved@[Content_Types].%78ml`)               |
| `esc-pct2F-slash-unreferenced`                   | #436       | `1003d9e0b112fcab` | repair-warning | valid                                                                       | invalid (`rels-unreferenced@word%2Fxtra.xml`)                                                                               |
| `esc-pct5C-backslash-unreferenced`               | #436       | `76f9efc51af63338` | open-error     | valid                                                                       | invalid (`rels-unreferenced@word%5Cxtra.xml`)                                                                               |
| `docprops-custom-unreferenced-undeclared-prefix` | #409       | `0a49797ea81f27d6` | clean-open     | valid                                                                       | invalid (`xml-undeclared-prefix@docProps/custom.xml`, `rels-unreferenced@docProps/custom.xml`)                              |
| `docprops-custom-unreferenced-truncated`         | #409       | `050e2698f564c761` | clean-open     | valid                                                                       | invalid (`xml-syntax@docProps/custom.xml`, `rels-unreferenced@docProps/custom.xml`)                                         |
| `docprops-app-unreferenced-truncated`            | #409       | `57b78d2872e4569a` | clean-open     | valid                                                                       | invalid (`xml-syntax@docProps/app.xml`, `rels-unreferenced@docProps/app.xml`)                                               |
| `word-unreferenced-malformed-part`               | #437       | `8968d3be05c61519` | clean-open     | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`) | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`, `rels-unreferenced@word/xtra.xml`)              |
| `word-unreferenced-wellformed-control`           | #437       | `7b8e0e0d4ae48b38` | clean-open     | valid                                                                       | invalid (`rels-unreferenced@word/xtra.xml`)                                                                                 |
| `docprops-core-unreferenced-truncated`           | #409       | `cefef105ee09a3c0` | clean-open     | valid                                                                       | invalid (`xml-syntax@docProps/core.xml`, `xml-undeclared-prefix@docProps/core.xml`, `rels-unreferenced@docProps/core.xml`)  |
| `docprops-core-renamed-truncated`                | #409       | `e0290e52e694e983` | repair-warning | valid                                                                       | invalid (`xml-syntax@props/meta.xml`, `xml-undeclared-prefix@props/meta.xml`)                                               |
| `docprops-core-renamed-control`                  | #409       | `de166f9b02fa683d` | clean-open     | valid                                                                       | valid                                                                                                                       |
| `empty-archive`                                  | #380       | `8739c76e681f9009` | repair-warning | valid                                                                       | invalid (`ct-missing`, `word-main-document-part`)                                                                           |
| `main-part-missing`                              | #380       | `035e63734f8226d0` | repair-warning | valid                                                                       | invalid (`rels-broken@_rels/.rels`, `rels-target-missing@_rels/.rels`, `word-main-document-part@_rels/.rels`)               |
| `main-relationship-missing`                      | #380       | `6cff8f9d94dc4883` | inconclusive   | valid                                                                       | invalid (`rels-unreferenced@word/document.xml`, `rels-empty-part@_rels/.rels`, `word-main-document-part@_rels/.rels`)       |
| `414-invalid-x-plain-missing-control`            | #414       | `dc5dafa7e6a85c49` | clean-open     | valid                                                                       | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                |
| `414-invalid-x-dotdot-missing`                   | #414       | `2bd531b03fb63a74` | repair-warning | valid                                                                       | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                |
| `414-invalid-x-query-missing`                    | #414       | `8c41377382c63da1` | open-error     | valid                                                                       | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                |
| `414-invalid-x-fragment-missing`                 | #414       | `ae39b41b00a82878` | repair-warning | valid                                                                       | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                |
| `414-invalid-x-backslash-missing`                | #414       | `8fc0c3015afe29b2` | repair-warning | valid                                                                       | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                |
| `rels-unknown-sibling-control`                   | #433       | `43205d2359aaac36` | repair-warning | valid                                                                       | invalid (`xsd-summary@_rels/.rels`, `xsd-error@_rels/.rels`)                                                                |

Full hashes, the driver's per-file result and every alert that named the file are in the session 3 records:

<details><summary>Raw records, session 3</summary>

```jsonl
{"name": "control-minimal", "sha256": "0160dfc1db4c5ce1e1f87f3b7547cae3bbe64240705ada3e54be8897de00ac1a", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "397-encoding-windows-1252-control", "sha256": "3ccb84b7f1be0b8885f311c6bb9aaa00e477e53780d16043ca6ea85cf766c633", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "351-dup-case-identical", "sha256": "4400bc4cd6b8d23ab6e049f1596436e744f9630cd9e3152f630f36dc63e1cb42", "observedAt": "2026-10-24T05:02:46.447Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__351-dup-case-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__351-dup-case-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "cti-override-existing-core-control", "sha256": "ae55ebebdd97a9712fcd7274520ebe8560b6acddd4443e07489780307d49181c", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "398-hyperlink-RELS", "sha256": "18b773c0d5d7ec6ff1b7127a461bc1a1852fbc644f0ce4df5e36079f6d4bde22", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-core-truncated", "sha256": "c8eb3d968d217f0c4f5a67a9770f246a81477f8c26093a48c6385a4f3aeda444", "observedAt": "2026-10-24T05:09:34.682Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00028__wfv__docprops-core-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00028__wfv__docprops-core-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-unreferenced-extra-item", "sha256": "d8ad7b6fa1e059379c1b0b0646261752d8184363fd2a8ea60f532a56960c9d53", "observedAt": "2026-10-24T05:16:54.733Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00048__wfv__esc-unreferenced-extra-item.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00048__wfv__esc-unreferenced-extra-item.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00048__wfv__esc-unreferenced-extra-item.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "397-encoding-unknown-core", "sha256": "031ee748acdee96d3007fc1d4be0fadfba9504d567509e86a9f630593366054e", "observedAt": "2026-10-24T05:02:49.147Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__397-encoding-unknown-core.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__397-encoding-unknown-core.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__397-encoding-unknown-core.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "s3-control-minimal-start", "sha256": "3cdc3192bc053374381bfd80959775fa792556e3f36fa7c884da45b1fba6d41b", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-app-truncated", "sha256": "96ef7c3a11c2d06add3f28257aeb145dcfdfd297e7b43b48de010da48e252a60", "observedAt": "2026-10-24T05:09:26.187Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00026__wfv__docprops-app-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00026__wfv__docprops-app-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-app-encoding-unknown", "sha256": "3a3d526f3519441538b7e89522c459cc5b1a1ac9465825dede6e1ad32dd7e848", "observedAt": "2026-10-24T05:09:21.748Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00025__wfv__docprops-app-encoding-unknown.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00025__wfv__docprops-app-encoding-unknown.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-app-undeclared-prefix", "sha256": "ee29efbb9af0ee63317e2f662bf312bc409b2ea77d3dd626966f23498bd49758", "observedAt": "2026-10-24T05:09:30.416Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00027__wfv__docprops-app-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00027__wfv__docprops-app-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-core-undeclared-prefix", "sha256": "9692d5b7434cea969c889bdc12d72b20e1e4cb6a74aa0c836cf566ebc86fb561", "observedAt": "2026-10-24T05:09:38.866Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00029__wfv__docprops-core-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00029__wfv__docprops-core-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-custom-control", "sha256": "a82099eacbd6b8ed10a40115643c17e3881ff4458a72e2e2f6e3e812c949bb56", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-custom-truncated", "sha256": "2619e0980a11bbf6b59e2b9feeb8eb28626a0e96d4ddc9bc873b8f319a59521e", "observedAt": "2026-10-24T05:09:47.518Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00032__wfv__docprops-custom-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00032__wfv__docprops-custom-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-custom-undeclared-prefix", "sha256": "de4ca7ce3c73f6706526db5e66e4c36272295a89d071dc2c8271b531f475e4fd", "observedAt": "2026-10-24T05:09:51.735Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00033__wfv__docprops-custom-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00033__wfv__docprops-custom-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-custom-encoding-unknown", "sha256": "1d03dad3ff19c572be1997564fb4b08e6ede0e796e82624124756089ecf6ab5c", "observedAt": "2026-10-24T05:09:43.317Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00031__wfv__docprops-custom-encoding-unknown.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00031__wfv__docprops-custom-encoding-unknown.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "410-macintosh", "sha256": "9f5a2e272d2e34cb55b14af966ba75d72cafd90595825dd3c3efabfb981105d7", "observedAt": "2026-10-24T05:03:15.432Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00006__wfv__410-macintosh.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "410-x-mac-cyrillic", "sha256": "81d8f59f16ff8e5d0d4ddb78556c080beea84718855b72827f8ef4c8d5da6eab", "observedAt": "2026-10-24T05:15:32.619Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00008__wfv__410-x-mac-cyrillic.docx; refusing to guess", "dialogs": ["\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "410-IBM866", "sha256": "b48036e2d2f7d93cbbae030e440f8b6e0e6263a8afc8fa32d57e4cd51abf6ebf", "observedAt": "2026-10-24T05:03:06.975Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__410-IBM866.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "410-UTF-7", "sha256": "6bf6863458ce8038a6139145bcd8f8e70ba5a2caf44906f3424c0da9956b4d2f", "observedAt": "2026-10-24T05:03:11.114Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__410-UTF-7.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "410-windows-1252-nonascii-control", "sha256": "e004e8ebb0082fbd1057891c719da2bfb677d78531af0c32f4e454360287441c", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "411-identical-valid-valid", "sha256": "ea01967dbdd157861518144f062b569b30a5a00f14db4e4a57c96d415dd9ce12", "observedAt": "2026-10-24T05:04:51.295Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00013__wfv__411-identical-valid-valid.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00013__wfv__411-identical-valid-valid.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "411-identical-valid-then-malformed", "sha256": "3ac694002959888c7edcabe5a0b2809f4128da71e3f2443b372eb8dc5fc440cb", "observedAt": "2026-10-24T05:04:45.803Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00012__wfv__411-identical-valid-then-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "411-identical-malformed-then-valid", "sha256": "4ada736ae140496eb2dad6d806719a8580e77de6f999d30f4136dec1b44cb37d", "observedAt": "2026-10-24T05:03:53.717Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00011__wfv__411-identical-malformed-then-valid.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00011__wfv__411-identical-malformed-then-valid.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00011__wfv__411-identical-malformed-then-valid.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "411-dotdot-unreferenced-item", "sha256": "97f752f1b03e1749d1c8950d7f83aa2e58aaa9c76292603ee4e6c165621a774b", "observedAt": "2026-10-24T05:03:41.732Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00010__wfv__411-dotdot-unreferenced-item.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00010__wfv__411-dotdot-unreferenced-item.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00010__wfv__411-dotdot-unreferenced-item.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "411-dotdot-then-plain-styles", "sha256": "e68121f4cf1076570a08982b11976d1cdbbb590a55148fc6c887e702a7a49bad", "observedAt": "2026-10-24T05:03:31.782Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00009__wfv__411-dotdot-then-plain-styles.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00009__wfv__411-dotdot-then-plain-styles.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00009__wfv__411-dotdot-then-plain-styles.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-styles-override-removed-control", "sha256": "e0595fa4e2e464ec4a3288b474b728226f587d933ac90e416fa36c5b7df7b9df", "observedAt": "2026-10-24T05:09:17.692Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00022__wfv__414-styles-override-removed-control.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00022__wfv__414-styles-override-removed-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "414-styles-override-dotdot", "sha256": "1fa751332e19b8f00e34ecf1007caaf479a50ba162fd324332c8c69645a50838", "observedAt": "2026-10-24T05:07:22.820Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00019__wfv__414-styles-override-dotdot.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00019__wfv__414-styles-override-dotdot.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "414-styles-override-query", "sha256": "75810dc3e308696a365b4131c39152371d0eb7d4eff33ca2dfe31113994a7139", "observedAt": "2026-10-24T05:08:24.569Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00021__wfv__414-styles-override-query.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00021__wfv__414-styles-override-query.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00021__wfv__414-styles-override-query.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-styles-override-fragment", "sha256": "7a16f99036a62688c7426afc8b360a0a7bb19d6f915964b5b1fad024d1ea4753", "observedAt": "2026-10-24T05:13:33.732Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00020__wfv__414-styles-override-fragment.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00020__wfv__414-styles-override-fragment.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "414-styles-override-backslash", "sha256": "4e5e85d63f2ee9c34982a3dbfd1d4253531e079d16357b2acbdbc0b666c97750", "observedAt": "2026-10-24T05:06:30.793Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00018__wfv__414-styles-override-backslash.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00018__wfv__414-styles-override-backslash.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00018__wfv__414-styles-override-backslash.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-dotdot-main", "sha256": "f7bae552bbd4fd8a29a6f758dd0f8200e5931ae8f95abd72f9f2028a11b5a996", "observedAt": "2026-10-24T05:04:59.679Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00015__wfv__414-invalid-x-dotdot-main.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00015__wfv__414-invalid-x-dotdot-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00015__wfv__414-invalid-x-dotdot-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-query-main", "sha256": "0ceb5371ecc1714b06bc9f670e23559bd5fcc3c977cac7e2ca4a42311a7f6ded", "observedAt": "2026-10-24T05:06:19.728Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00017__wfv__414-invalid-x-query-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00017__wfv__414-invalid-x-query-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-fragment-main", "sha256": "00fb33975b0027c9e8f1ee38a72ee026c73f330b751ba700b251873d62f22d72", "observedAt": "2026-10-24T05:05:46.744Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00016__wfv__414-invalid-x-fragment-main.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00016__wfv__414-invalid-x-fragment-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00016__wfv__414-invalid-x-fragment-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-backslash-main", "sha256": "f6451c46a832393860a5ea916b28de226ade0cc46cd47b68d7913b0a01b8a5a4", "observedAt": "2026-10-24T05:04:55.509Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00014__wfv__414-invalid-x-backslash-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00014__wfv__414-invalid-x-backslash-main.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "dupdecl-default-identical", "sha256": "222d7ee2fc43b1f6fa373efa5f8918f02a1a53a6234052e5945327c2be957873", "observedAt": "2026-10-24T05:10:00.151Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00035__wfv__dupdecl-default-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00035__wfv__dupdecl-default-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "dupdecl-default-case", "sha256": "fe596b4f8f32a55c1108ef7d3e0fcdca54bf5a5558ba249114f12b90fe2dc656", "observedAt": "2026-10-24T05:09:55.950Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00034__wfv__dupdecl-default-case.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00034__wfv__dupdecl-default-case.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "dupdecl-override-identical", "sha256": "92c289efb80c1b4171d3da146063eea94a8fa742b1ce979d98db6f0a9d01b110", "observedAt": "2026-10-24T05:10:12.787Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00038__wfv__dupdecl-override-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00038__wfv__dupdecl-override-identical.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "dupdecl-override-conflicting", "sha256": "1fe83fb76ef60ec209e7148ecb8f45eb5bd395abbc35095374c19763163328e6", "observedAt": "2026-10-24T05:10:08.582Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00037__wfv__dupdecl-override-conflicting.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00037__wfv__dupdecl-override-conflicting.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "dupdecl-override-case", "sha256": "2f9f7277561b364b8ef0153456571f844b0eaf05dba51c9ca3f8346e67046aac", "observedAt": "2026-10-24T05:10:04.365Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00036__wfv__dupdecl-override-case.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00036__wfv__dupdecl-override-case.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-plain-unreferenced-control", "sha256": "6e63642feef861ab8d78183d4d9fc19387179c4605ca42af6a25fb642b04ec41", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "esc-%41-upper-letter", "sha256": "fae72ee8b638fa8a70e690ba666383a1bde0f9605b27c84996d99ac14106ec8e", "observedAt": "2026-10-24T05:10:34.149Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00044__wfv__esc-pct41-upper-letter.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00044__wfv__esc-pct41-upper-letter.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%30-digit", "sha256": "17d763961bc3f58c062f92c6a00005b8bee15200a3f6ce251d3310d5db7dc134", "observedAt": "2026-10-24T05:10:29.952Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00043__wfv__esc-pct30-digit.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00043__wfv__esc-pct30-digit.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%2D-hyphen", "sha256": "84a0e0f1843139fd42dfcf81ce7f84f5f2882d445cdb4814c6883516b30d99a5", "observedAt": "2026-10-24T05:10:17.302Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00040__wfv__esc-pct2D-hyphen.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00040__wfv__esc-pct2D-hyphen.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%2d-hyphen-lowerhex", "sha256": "37529d0e79b352aa3d1b870d9157b18b437c83e640d21cfbf001ce01c0a71f98", "observedAt": "2026-10-24T05:10:25.767Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00042__wfv__esc-pct2d-hyphen-lowerhex.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00042__wfv__esc-pct2d-hyphen-lowerhex.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%2E-period", "sha256": "fcbdbbf79faa0bcd6da0f0534059fdc0797cb4314c7f44eb9493499de0c13d9f", "observedAt": "2026-10-24T05:10:21.519Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00041__wfv__esc-pct2E-period.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00041__wfv__esc-pct2E-period.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%5F-underscore", "sha256": "7d0278c4bf9fd3fa41dadb456cd2e31091f92135e4bfc678bb6f137646da52de", "observedAt": "2026-10-24T05:10:38.399Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00045__wfv__esc-pct5F-underscore.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00045__wfv__esc-pct5F-underscore.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00045__wfv__esc-pct5F-underscore.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%7E-tilde", "sha256": "4436f009f2500d574870504a3c6abdffab59ea97bc5d50416f7784a0ff1c847c", "observedAt": "2026-10-24T05:11:33.011Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00046__wfv__esc-pct7E-tilde.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00046__wfv__esc-pct7E-tilde.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00046__wfv__esc-pct7E-tilde.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-%20-space-control", "sha256": "c7598087941b0c35b84765110d5289c53c86b0675fcdfe31db21ba23def5d1f9", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "s3-control-minimal-end", "sha256": "00d28798c1f66dc7dfd1f484e065d729fe95fdc34a4491be031f3750b59ef3d6", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "rels-main-nested-in-unknown-element", "sha256": "176e6d8f133812b3de0d01186fcf6f950b700a993d5b6cec7ec3c523b65ececc", "observedAt": "2026-10-24T05:11:58.058Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00049__wfv__rels-main-nested-in-unknown-element.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "rels-root-not-relationships", "sha256": "1a5c659713cf7f9b7ba3aef608df5c3ce6e583de2747c4b58a06437f53ef52e7", "observedAt": "2026-10-24T05:12:38.604Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00050__wfv__rels-root-not-relationships.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00050__wfv__rels-root-not-relationships.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00050__wfv__rels-root-not-relationships.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "rels-unknown-sibling-control", "sha256": "27cb9b0032c7b10c88fc12f5eb47a7b8a9b8845b30ce867f3bd9d33725f98241", "observedAt": "2026-10-24T05:18:09+00:00", "outcome": "other", "item": "failed", "error": "Word could not load it in 2 passes: open produced 1 new documents, none named 00051__wfv__rels-unknown-sibling-control.docx; refusing to guess", "dialogs": []}
{"name": "s3c-control-minimal", "sha256": "1a414a1109291a1823ea0a0bb5be8cd5659634f1614aa961e3bc0cf239cad4a1", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "ct-stream-missing-control", "sha256": "a4c6ecaf2f422b09f82284c73c9f288b2488c67bf00e880a82394edc15a012e9", "observedAt": "2026-10-24T05:22:07.264Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__ct-stream-missing-control.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter.", "'Word found unreadable content in 00007__wfv__ct-stream-missing-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__ct-stream-missing-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "ct-stream-escaped-only", "sha256": "42d70cff0d0d0e1a44ea46f743cd749ff62cc6b527736670c26e6a878f23acf0", "observedAt": "2026-10-24T05:21:51.014Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__ct-stream-escaped-only.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00006__wfv__ct-stream-escaped-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__ct-stream-escaped-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "ct-stream-escaped-extra", "sha256": "898d49c3184b8458d67dcb5a880191c4fcae67be06bfb36d89eda6579391f211", "observedAt": "2026-10-24T05:21:03.646Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__ct-stream-escaped-extra.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00005__wfv__ct-stream-escaped-extra.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__ct-stream-escaped-extra.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "esc-pct2F-slash-unreferenced", "sha256": "1003d9e0b112fcabc3d0f00533e7080bcf497d8d54749a7cd3627efd980e446d", "observedAt": "2026-10-24T05:23:30.476Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00015__wfv__esc-pct2F-slash-unreferenced.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00015__wfv__esc-pct2F-slash-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "esc-pct5C-backslash-unreferenced", "sha256": "76f9efc51af63338b83fe1cfcc23098aaaeb5f8f6bfae30f6315b7f84ebf535a", "observedAt": "2026-10-24T05:25:16.693Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00016__wfv__esc-pct5C-backslash-unreferenced.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-custom-unreferenced-undeclared-prefix", "sha256": "0a49797ea81f27d6dfad5601bbd0cf1fc6e3b8ccafbd66d124d59b5e2663b548", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-custom-unreferenced-truncated", "sha256": "050e2698f564c7613ff607cbb7f0e3ff8d0bd276d2804895b25112f4d28a906b", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-app-unreferenced-truncated", "sha256": "57b78d2872e4569a66fc96367672372a0a63e17c36ad6368871d4c81c158d0bb", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "word-unreferenced-malformed-part", "sha256": "8968d3be05c61519b5636bb63aa5fb1107897af6aa3dd4c98d9a282fb462bd31", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "word-unreferenced-wellformed-control", "sha256": "7b8e0e0d4ae48b381266fab8968c6c24697dd6072b94a84aab928be96bb379ea", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-core-unreferenced-truncated", "sha256": "cefef105ee09a3c0dee534f9cf65b12214805ec81b9c1689b44baf4ef61a5e2a", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "docprops-core-renamed-truncated", "sha256": "e0290e52e694e983777f6affaca16d6152ca7471fe3617031a673c713a799522", "observedAt": "2026-10-24T05:22:11.750Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00010__wfv__docprops-core-renamed-truncated.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00010__wfv__docprops-core-renamed-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00010__wfv__docprops-core-renamed-truncated.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "docprops-core-renamed-control", "sha256": "de166f9b02fa683d138d0eb981a182681e37bcceba73d77feebfb6215051f65e", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "empty-archive", "sha256": "8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85", "observedAt": "2026-10-24T05:22:33.454Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00014__wfv__empty-archive.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00014__wfv__empty-archive.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"name": "main-part-missing", "sha256": "035e63734f8226d0c0dc5022ac68287e13f24b82d78b0e86ff775faa5e97ae8a", "observedAt": "2026-10-24T05:25:33.299Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00017__wfv__main-part-missing.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00017__wfv__main-part-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00017__wfv__main-part-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "main-relationship-missing", "sha256": "6cff8f9d94dc4883be54782e873a345840856291f15a33fb6f31d3c351917890", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "other", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00018__wfv__main-relationship-missing.docx; refusing to guess", "dialogs": []}
{"name": "414-invalid-x-plain-missing-control", "sha256": "dc5dafa7e6a85c49308d2a5571e5d8042fff7f6b6d528a2959a127b55bc175ae", "observedAt": "2026-10-24T05:26:57+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"name": "414-invalid-x-dotdot-missing", "sha256": "2bd531b03fb63a740f04a71d312914e1ab7d4eb01bd7e0ca88bb74a5bf48b9de", "observedAt": "2026-10-24T05:26:52.613Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__414-invalid-x-dotdot-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__414-invalid-x-dotdot-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-query-missing", "sha256": "8c41377382c63da1d8dd90a9d730620e896f220b3f083083618d3e93c7d3f5e1", "observedAt": "2026-10-24T05:20:59.363Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__414-invalid-x-query-missing.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "414-invalid-x-fragment-missing", "sha256": "ae39b41b00a82878ad7785ad3b46ba8aac1351d748316ecc5a15092d36a5ac61", "observedAt": "2026-10-24T05:20:39.296Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__414-invalid-x-fragment-missing.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__414-invalid-x-fragment-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__414-invalid-x-fragment-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter.", "'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver"]}
{"name": "414-invalid-x-backslash-missing", "sha256": "8fc0c3015afe29b28a7acbb5e14da9195b110d9220f330cb22d6143788c81e00", "observedAt": "2026-10-24T05:19:49.448Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__414-invalid-x-backslash-missing.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__414-invalid-x-backslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-invalid-x-backslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
{"name": "rels-unknown-sibling-control", "sha256": "43205d2359aaac364bd348acd4205514d8572e334162a08ed113d02fa9eb826b", "observedAt": "2026-10-24T05:26:22.486Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00019__wfv__rels-unknown-sibling-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00019__wfv__rels-unknown-sibling-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file. / Try these suggestions. / * Check the file permissions for the document or drive. / * Make sure there is sufficient free memory and disk space. / * Open the file with the Text Recovery converter."]}
```

</details>

### Session 4: 06:02Z–06:11Z, validator columns at 3126dcfc

Runs `s4a` (06:02Z–06:04Z), `s4b` (06:04Z–06:10Z) and `s4c` (06:11Z), in the foreground. `s4c` re-runs `rels-part-level-unknown-sibling` alone after the `s4b` interference described under "Not observed". Every run opens the unchanged `MINIMAL_PARTS` control first.

| Run   | Observed  | Specimen                                | Issue   | SHA-256 (first 16) | Word           | word-valid at 3126dcfc                                               | strict at 3126dcfc                                                                                                                                         |
| ----- | --------- | --------------------------------------- | ------- | ------------------ | -------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s4a` | 06:04:22Z | `s4-control-minimal`                    | control | `f67e18fa7a50dae1` | clean-open     | valid                                                                | valid                                                                                                                                                      |
| `s4a` | 06:04:21Z | `main-relationship-missing`             | #380    | `55d82b16632f6df3` | repair-warning | valid                                                                | invalid (`rels-unreferenced@word/document.xml`, `rels-empty-part@_rels/.rels`, `word-main-document-part@_rels/.rels`)                                      |
| `s4a` | 06:04:22Z | `414-xml-plain-missing-control`         | #414    | `f4b6ac54fdf7ad68` | clean-open     | valid                                                                | valid                                                                                                                                                      |
| `s4a` | 06:02:31Z | `414-xml-dotdot-missing`                | #414    | `a786c14afc50dc3f` | repair-warning | valid                                                                | valid                                                                                                                                                      |
| `s4a` | 06:03:36Z | `414-xml-query-missing`                 | #414    | `95fd95244fbbb384` | repair-warning | valid                                                                | valid                                                                                                                                                      |
| `s4a` | 06:03:23Z | `414-xml-fragment-missing`              | #414    | `8a41c9430a5077b2` | repair-warning | valid                                                                | valid                                                                                                                                                      |
| `s4b` | 06:10:40Z | `s4-control-minimal`                    | control | `f67e18fa7a50dae1` | clean-open     | valid                                                                | valid                                                                                                                                                      |
| `s4b` | 06:05:26Z | `414-xml-backslash-missing`             | #414    | `02daab8408c136f3` | repair-warning | valid                                                                | valid                                                                                                                                                      |
| `s4b` | 06:06:01Z | `esc-folder-segment-unreferenced`       | #408    | `4fec8690b781619a` | repair-warning | invalid (`opc-part-name-escaped-unreserved@f%6Fo/xtra.xml`)          | invalid (`rels-unreferenced@f%6Fo/xtra.xml`, `opc-part-name-escaped-unreserved@f%6Fo/xtra.xml`)                                                            |
| `s4b` | 06:10:40Z | `esc-folder-plain-unreferenced-control` | #408    | `dc73c8062ac67960` | clean-open     | valid                                                                | invalid (`rels-unreferenced@foo/xtra.xml`)                                                                                                                 |
| `s4b` | 06:10:40Z | `customxml-unreferenced-malformed`      | #437    | `b916c943fb72fed2` | clean-open     | valid                                                                | invalid (`xml-syntax@customXml/item9.xml`, `xml-undeclared-prefix@customXml/item9.xml`, `rels-unreferenced@customXml/item9.xml`)                           |
| `s4b` | 06:10:40Z | `s4-control-minimal-end`                | control | `bbb873d65445e842` | clean-open     | valid                                                                | valid                                                                                                                                                      |
| `s4c` | 06:11:51Z | `s4-control-minimal`                    | control | `f67e18fa7a50dae1` | clean-open     | valid                                                                | valid                                                                                                                                                      |
| `s4c` | 06:11:49Z | `rels-part-level-unknown-sibling`       | #433    | `e7dae629d3e792a1` | repair-warning | invalid (`opc-relationships-structure@word/_rels/document.xml.rels`) | invalid (`opc-relationships-structure@word/_rels/document.xml.rels`, `xsd-summary@word/_rels/document.xml.rels`, `xsd-error@word/_rels/document.xml.rels`) |

### Session 4d: 06:29Z–06:52Z, review Y name-source specimens

These specimens come from review Y of #411. Each one stores a name in the ZIP central directory that differs from the name in its local file header (`localName`), or carries an Info-ZIP unicode path extra field (0x7075) naming something else. They are built with the review's raw ZIP builder (reproduced at the end of this file). Four specimens timed out in the `s4d` batch (06:29Z–06:38Z), and each was then observed alone, in its own run, from 06:51Z to 06:52Z.

| Run                                 | Observed  | Specimen                        | Issue           | SHA-256 (first 16) | Word           | word-valid at 3126dcfc                                  | strict at 3126dcfc                                                                                                                                                                                                                                                                                               |
| ----------------------------------- | --------- | ------------------------------- | --------------- | ------------------ | -------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s4d`                               | 06:29:29Z | `ry-central-dotdot-local-clean` | #411 (review Y) | `1d93703f65dded1c` | repair-warning | invalid (`package-extract-failed@-`)                    | invalid (`package-extract-failed@-`)                                                                                                                                                                                                                                                                             |
| `s4d`                               | 06:38:30Z | `ry-upath-injects-dotdot`       | #411 (review Y) | `a42466f496e3fe29` | clean-open     | invalid (`package-extract-failed@-`)                    | invalid (`package-extract-failed@-`)                                                                                                                                                                                                                                                                             |
| `s4d`                               | 06:38:30Z | `s4-control-minimal`            | control         | `f67e18fa7a50dae1` | clean-open     | valid                                                   | valid                                                                                                                                                                                                                                                                                                            |
| `s4d-ry-local-dotdot`               | 06:51:48Z | `ry-local-dotdot`               | #411 (review Y) | `6acbd947d1520f66` | clean-open     | invalid (`package-extract-failed@-`)                    | invalid (`package-extract-failed@-`)                                                                                                                                                                                                                                                                             |
| `s4d-ry-upath-hides-dotdot`         | 06:52:00Z | `ry-upath-hides-dotdot`         | #411 (review Y) | `a9acc5ce9b27584f` | repair-warning | invalid (`package-extract-failed@-`)                    | invalid (`package-extract-failed@-`)                                                                                                                                                                                                                                                                             |
| `s4d-ry-cp437-name`                 | 06:52:25Z | `ry-cp437-name`                 | #411 (review Y) | `a4a3ca9d143cc102` | repair-warning | valid                                                   | invalid (`rels-unreferenced@caf�.xml`)                                                                                                                                                                                                                                                                           |
| `s4d-ry-dup-central-distinct-local` | 06:52:37Z | `ry-dup-central-distinct-local` | #411 (review Y) | `4714e2e148094463` | repair-warning | invalid (`opc-equivalent-part-names@word/document.xml`) | invalid (`rels-broken@_rels/.rels`, `rels-unreferenced@AAAA-first.xml`, `rels-unreferenced@BBBB-second.xml`, `ct-undeclared-part@AAAA-first.xml`, `ct-undeclared-part@BBBB-second.xml`, `rels-target-missing@_rels/.rels`, `word-main-document-part@_rels/.rels`, `opc-equivalent-part-names@word/document.xml`) |

### Session 5: 06:50Z–07:03Z, validator columns at 3126dcfc

Every row here comes from a single-specimen run. The `s5a` batch (06:38Z–06:49Z) was set aside; see "Not observed".

| Run                                           | Observed  | Specimen                                          | Issue   | SHA-256 (first 16) | Word           | word-valid at 3126dcfc                                                      | strict at 3126dcfc                                                                                             |
| --------------------------------------------- | --------- | ------------------------------------------------- | ------- | ------------------ | -------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `s5a1`                                        | 06:50:11Z | `414-xml-emptyseg-missing`                        | #414    | `20218cb25f2b8d60` | repair-warning | valid                                                                       | valid                                                                                                          |
| `s5a-noslash`                                 | 06:50:28Z | `414-xml-noslash-missing`                         | #414    | `7d463dbaee257bb0` | repair-warning | valid                                                                       | valid                                                                                                          |
| `s5a-pct2F`                                   | 06:50:37Z | `414-xml-pct2F-missing`                           | #414    | `6644f808ea36030a` | repair-warning | valid                                                                       | valid                                                                                                          |
| `s5a-pct6F`                                   | 06:50:46Z | `414-xml-pct6F-missing`                           | #414    | `be2329c386b7d7d4` | repair-warning | valid                                                                       | valid                                                                                                          |
| `s5a-ctl`                                     | 06:50:52Z | `s5-control-minimal`                              | control | `49873da1ea328db9` | clean-open     | valid                                                                       | valid                                                                                                          |
| `s5a-trail`                                   | 07:02:54Z | `414-xml-trailing-slash-missing`                  | #414    | `c2b3f563e8d487dd` | repair-warning | valid                                                                       | valid                                                                                                          |
| `s5b-437-unknown-type-rel-malformed`          | 06:51:05Z | `437-unknown-type-rel-malformed`                  | #437    | `73c409fd62d90061` | clean-open     | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`) | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`)                                    |
| `s5b-437-unknown-type-rel-wellformed-control` | 06:51:12Z | `437-unknown-type-rel-wellformed-control`         | #437    | `ad4f5885055e3487` | clean-open     | valid                                                                       | valid                                                                                                          |
| `s5b-437-unreferenced-malformed-override`     | 06:51:19Z | `437-unreferenced-malformed-override`             | #437    | `4324f39b802724c7` | clean-open     | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`) | invalid (`xml-syntax@word/xtra.xml`, `xml-undeclared-prefix@word/xtra.xml`, `rels-unreferenced@word/xtra.xml`) |
| `s5b-409-type-trailing-space-core-truncated`  | 06:51:25Z | `409-type-trailing-space-core-truncated`          | #409    | `ab749355bcb6a6c7` | clean-open     | valid                                                                       | invalid (`xml-syntax@docProps/core.xml`, `xml-undeclared-prefix@docProps/core.xml`)                            |
| `s5b-tail`                                    | 06:51:41Z | `409-type-trailing-space-core-wellformed-control` | #409    | `c52e6feee3dd0d53` | clean-open     | valid                                                                       | valid                                                                                                          |
| `s5b-tail`                                    | 06:51:41Z | `s5-control-minimal-end`                          | control | `49873da1ea328db9` | clean-open     | valid                                                                       | valid                                                                                                          |

### Session 6: 06:56Z–06:59Z, validator columns at 3126dcfc

Each specimen is `MINIMAL_PARTS` plus one extra entry holding `<x/>`. The entry is covered by the `xml` Default and named by no relationship; only its stored name varies. Each was observed alone. `s6-cp437-byte-noflag` is byte-identical to review Y's `ry-cp437-name` above, so its outcome was observed twice.

| Run                            | Observed  | Specimen                   | Issue | SHA-256 (first 16) | Word           | word-valid at 3126dcfc | strict at 3126dcfc                                                                                  |
| ------------------------------ | --------- | -------------------------- | ----- | ------------------ | -------------- | ---------------------- | --------------------------------------------------------------------------------------------------- |
| `s6a-s6-ascii-control`         | 06:56:43Z | `s6-ascii-control`         | #443  | `552826505c024774` | clean-open     | valid                  | invalid (`rels-unreferenced@cafe.xml`)                                                              |
| `s6a-s6-cp437-byte-noflag`     | 06:56:58Z | `s6-cp437-byte-noflag`     | #443  | `a4a3ca9d143cc102` | repair-warning | valid                  | invalid (`rels-unreferenced@caf�.xml`)                                                              |
| `s6a-s6-utf8-bytes-flag`       | 06:57:13Z | `s6-utf8-bytes-flag`       | #443  | `8c537b95b8930a88` | repair-warning | valid                  | invalid (`rels-unreferenced@café.xml`)                                                              |
| `s6a-s6-utf8-bytes-noflag`     | 06:57:27Z | `s6-utf8-bytes-noflag`     | #443  | `df6ea023437e29f7` | repair-warning | valid                  | invalid (`rels-unreferenced@café.xml`)                                                              |
| `s6a-s6-pct-encoded-ascii`     | 06:57:41Z | `s6-pct-encoded-ascii`     | #443  | `55bc366c36cdee2a` | repair-warning | valid                  | invalid (`rels-unreferenced@caf%C3%A9.xml`)                                                         |
| `s6b-s6-ascii-control-in-word` | 06:58:20Z | `s6-ascii-control-in-word` | #443  | `055d1dbf8ae1d2da` | clean-open     | valid                  | invalid (`rels-unreferenced@word/cafe.xml`, `xsd-summary@word/cafe.xml`, `xsd-error@word/cafe.xml`) |
| `s6b-s6-pct-ascii-space-root`  | 06:58:30Z | `s6-pct-ascii-space-root`  | #443  | `0a7d3a4ea2f15219` | clean-open     | valid                  | invalid (`rels-unreferenced@caf%20.xml`)                                                            |
| `s6b-s6-pct-latin1-e9`         | 06:58:44Z | `s6-pct-latin1-e9`         | #443  | `222cab2384ca8eb9` | repair-warning | valid                  | invalid (`rels-unreferenced@caf%E9.xml`)                                                            |
| `s6b-s6-utf8-flag-in-word`     | 06:59:04Z | `s6-utf8-flag-in-word`     | #443  | `c9317c54a63b0094` | repair-warning | valid                  | invalid (`rels-unreferenced@word/café.xml`, `xsd-summary@word/café.xml`, `xsd-error@word/café.xml`) |

The driver's per-file result and every alert that named the file are in the session 4–6 records. The records include the set-aside `s4b`, `s4d` and `s5a` batch rows:

<details><summary>Raw records, sessions 4–6</summary>

```jsonl
{"run": "s4a", "name": "s4-control-minimal", "sha256": "f67e18fa7a50dae1134be311356ce76be4722a435a514f30d9f65a77bab3ee08", "observedAt": "2026-10-24T06:04:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4a", "name": "main-relationship-missing", "sha256": "55d82b16632f6df34eccbbee438f74ea8f25303d39a4204a778a372b264634e8", "observedAt": "2026-10-24T06:04:21.829Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word found unreadable content in 00004__wfv__main-relationship-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s4a", "name": "414-xml-plain-missing-control", "sha256": "f4b6ac54fdf7ad6834c52dd5f6c81fa19b1d7cb266ed5a17fd64f8fb7eb4d1f8", "observedAt": "2026-10-24T06:04:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4a", "name": "414-xml-dotdot-missing", "sha256": "a786c14afc50dc3f1b71950a82ac6eccff3eaf8ce3ee03d0c4c4af6bb1081f62", "observedAt": "2026-10-24T06:02:31.633Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__414-xml-dotdot-missing.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00000__wfv__414-xml-dotdot-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s4a", "name": "414-xml-query-missing", "sha256": "95fd95244fbbb3843cdaacdbb2ca3eda11fdfdd0afd375e25bab01d18caf89d3", "observedAt": "2026-10-24T06:03:36.373Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00003__wfv__414-xml-query-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s4a", "name": "414-xml-fragment-missing", "sha256": "8a41c9430a5077b239d8674fcd77d20b1715d7048743ca2719e689f887ef9a97", "observedAt": "2026-10-24T06:03:23.306Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__414-xml-fragment-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__414-xml-fragment-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4b", "name": "s4-control-minimal", "sha256": "f67e18fa7a50dae1134be311356ce76be4722a435a514f30d9f65a77bab3ee08", "observedAt": "2026-10-24T06:10:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4b", "name": "414-xml-backslash-missing", "sha256": "02daab8408c136f347a4a9bf60b4c0162a5175920a4c4a93db52ffe320033462", "observedAt": "2026-10-24T06:05:26.041Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-backslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-backslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s4b", "name": "esc-folder-segment-unreferenced", "sha256": "4fec8690b781619a27d4f0f9b113f9c1bed479d786721227a35ae7b5e6f994ae", "observedAt": "2026-10-24T06:06:01.539Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__esc-folder-segment-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__esc-folder-segment-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4b", "name": "esc-folder-plain-unreferenced-control", "sha256": "dc73c8062ac67960d339fcadc90bb56a79dce2f8b2c7ba1e832feeb7252a4bdd", "observedAt": "2026-10-24T06:10:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4b", "name": "customxml-unreferenced-malformed", "sha256": "b916c943fb72fed284a07b503825f8255342fffce1e4ab4ef20b15ef54d816bb", "observedAt": "2026-10-24T06:10:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4b", "name": "rels-part-level-unknown-sibling", "sha256": "e7dae629d3e792a11c21af3ac421347432a584509974e83f85e089b0a2431cca", "observedAt": "2026-10-24T06:10:40+00:00", "outcome": "other", "item": "failed", "error": "Microsoft Word got an error: AppleEvent timed out.", "dialogs": []}
{"run": "s4b", "name": "s4-control-minimal-end", "sha256": "bbb873d65445e842301cbbd5e486d20a1cd4a3c1b9297e6ba26e0ad0943f6669", "observedAt": "2026-10-24T06:10:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4c", "name": "s4-control-minimal", "sha256": "f67e18fa7a50dae1134be311356ce76be4722a435a514f30d9f65a77bab3ee08", "observedAt": "2026-10-24T06:11:51+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4c", "name": "rels-part-level-unknown-sibling", "sha256": "e7dae629d3e792a11c21af3ac421347432a584509974e83f85e089b0a2431cca", "observedAt": "2026-10-24T06:11:49.529Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__rels-part-level-unknown-sibling.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__rels-part-level-unknown-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__rels-part-level-unknown-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4d", "name": "ry-central-dotdot-local-clean", "sha256": "1d93703f65dded1c913de6c23c590b1987565015b5fef4a8d704214a75e3caf7", "observedAt": "2026-10-24T06:29:29.512Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__ry-central-dotdot-local-clean.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__ry-central-dotdot-local-clean.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__ry-central-dotdot-local-clean.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4d", "name": "ry-cp437-name", "sha256": "a4a3ca9d143cc102a6b87b441496ff7ff9d13c816945c522d966076132de55dd", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "other", "item": "failed", "error": "Microsoft Word got an error: AppleEvent timed out.", "dialogs": []}
{"run": "s4d", "name": "ry-dup-central-distinct-local", "sha256": "4714e2e148094463665d2d084fb2f9afb4b6256fd9db9a77e4fd6514c206332a", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "other", "item": "failed", "error": "Microsoft Word got an error: AppleEvent timed out.", "dialogs": []}
{"run": "s4d", "name": "ry-local-dotdot", "sha256": "6acbd947d1520f6697c4c80547e6cf95d1ac91dc77388eef18d2047a9ebb7c21", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "other", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00003__wfv__ry-local-dotdot.docx; refusing to guess", "dialogs": []}
{"run": "s4d", "name": "ry-upath-hides-dotdot", "sha256": "a9acc5ce9b27584f5e0ab7320611c7f424b19ab4e4f46cae1232005662ce1cfb", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "other", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__ry-upath-hides-dotdot.docx; refusing to guess", "dialogs": []}
{"run": "s4d", "name": "ry-upath-injects-dotdot", "sha256": "a42466f496e3fe29aaf21345c2a5c98bb144370e5de0d5bfe410361420202857", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4d", "name": "s4-control-minimal", "sha256": "f67e18fa7a50dae1134be311356ce76be4722a435a514f30d9f65a77bab3ee08", "observedAt": "2026-10-24T06:38:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4d-ry-local-dotdot", "name": "ry-local-dotdot", "sha256": "6acbd947d1520f6697c4c80547e6cf95d1ac91dc77388eef18d2047a9ebb7c21", "observedAt": "2026-10-24T06:51:48+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s4d-ry-upath-hides-dotdot", "name": "ry-upath-hides-dotdot", "sha256": "a9acc5ce9b27584f5e0ab7320611c7f424b19ab4e4f46cae1232005662ce1cfb", "observedAt": "2026-10-24T06:52:00.575Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__ry-upath-hides-dotdot.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__ry-upath-hides-dotdot.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4d-ry-cp437-name", "name": "ry-cp437-name", "sha256": "a4a3ca9d143cc102a6b87b441496ff7ff9d13c816945c522d966076132de55dd", "observedAt": "2026-10-24T06:52:25.876Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__ry-cp437-name.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__ry-cp437-name.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s4d-ry-dup-central-distinct-local", "name": "ry-dup-central-distinct-local", "sha256": "4714e2e148094463665d2d084fb2f9afb4b6256fd9db9a77e4fd6514c206332a", "observedAt": "2026-10-24T06:52:37.857Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__ry-dup-central-distinct-local.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__ry-dup-central-distinct-local.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5a", "name": "s5-control-minimal", "sha256": "49873da1ea328db901ffdfe1da3a4143cddd4a2ffc4bf6df462936dac2aebdb5", "observedAt": "", "outcome": "other", "item": "missing", "error": "", "dialogs": []}
{"run": "s5a", "name": "414-xml-noslash-missing", "sha256": "7d463dbaee257bb0db2479696a13c19da1db592a460cf9647719a20bcdb5d524", "observedAt": "", "outcome": "other", "item": "missing", "error": "", "dialogs": []}
{"run": "s5a", "name": "414-xml-emptyseg-missing", "sha256": "20218cb25f2b8d60765093355c2f9c8baa754aeb21fe5be74bc5fe3ffe04dc13", "observedAt": "", "outcome": "other", "item": "missing", "error": "", "dialogs": []}
{"run": "s5a", "name": "414-xml-trailing-slash-missing", "sha256": "c2b3f563e8d487dd266fc7b2bd718f6360463938eb3c6c5405e2e37341e49dcb", "observedAt": "2026-10-24T06:44:19.836Z", "outcome": "repair-warning", "item": "missing", "error": "", "dialogs": ["'Word found unreadable content in 00004__wfv__414-xml-trailing-slash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__414-xml-trailing-slash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s5a", "name": "414-xml-pct2F-missing", "sha256": "6644f808ea36030a4f2b9f6be435144d3b5bf75ab4e6453bc866ffa4d953666a", "observedAt": "", "outcome": "other", "item": "missing", "error": "", "dialogs": []}
{"run": "s5a", "name": "414-xml-pct6F-missing", "sha256": "be2329c386b7d7d4e7cc5600bb142b07e070fa55fc66719aed4ae659f75ec399", "observedAt": "", "outcome": "other", "item": "missing", "error": "", "dialogs": []}
{"run": "s5a1", "name": "414-xml-emptyseg-missing", "sha256": "20218cb25f2b8d60765093355c2f9c8baa754aeb21fe5be74bc5fe3ffe04dc13", "observedAt": "2026-10-24T06:50:11.300Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-emptyseg-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-emptyseg-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5a-noslash", "name": "414-xml-noslash-missing", "sha256": "7d463dbaee257bb0db2479696a13c19da1db592a460cf9647719a20bcdb5d524", "observedAt": "2026-10-24T06:50:28.284Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-noslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-noslash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5a-pct2F", "name": "414-xml-pct2F-missing", "sha256": "6644f808ea36030a4f2b9f6be435144d3b5bf75ab4e6453bc866ffa4d953666a", "observedAt": "2026-10-24T06:50:37.417Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-pct2F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-pct2F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5a-pct6F", "name": "414-xml-pct6F-missing", "sha256": "be2329c386b7d7d4e7cc5600bb142b07e070fa55fc66719aed4ae659f75ec399", "observedAt": "2026-10-24T06:50:46.600Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-pct6F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-pct6F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5a-ctl", "name": "s5-control-minimal", "sha256": "49873da1ea328db901ffdfe1da3a4143cddd4a2ffc4bf6df462936dac2aebdb5", "observedAt": "2026-10-24T06:50:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5a-trail", "name": "414-xml-trailing-slash-missing", "sha256": "c2b3f563e8d487dd266fc7b2bd718f6360463938eb3c6c5405e2e37341e49dcb", "observedAt": "2026-10-24T07:02:54.487Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-trailing-slash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-trailing-slash-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s5b-437-unknown-type-rel-malformed", "name": "437-unknown-type-rel-malformed", "sha256": "73c409fd62d90061679cf0cba74df632c0a141b50a832e1156218a95a254c24d", "observedAt": "2026-10-24T06:51:05+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5b-437-unknown-type-rel-wellformed-control", "name": "437-unknown-type-rel-wellformed-control", "sha256": "ad4f5885055e3487d80915b204fb05453172d83b18844085c796341196681fb9", "observedAt": "2026-10-24T06:51:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5b-437-unreferenced-malformed-override", "name": "437-unreferenced-malformed-override", "sha256": "4324f39b802724c7222668b335bd81ea16d467989d845e200b9845fa24f0eaff", "observedAt": "2026-10-24T06:51:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5b-409-type-trailing-space-core-truncated", "name": "409-type-trailing-space-core-truncated", "sha256": "ab749355bcb6a6c7af15526763e90cbfd4794013f1248a39c044e5ad3edef344", "observedAt": "2026-10-24T06:51:25+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5b-tail", "name": "409-type-trailing-space-core-wellformed-control", "sha256": "c52e6feee3dd0d53282c8add84563576d775860a0abf83db9750b5d8858337cf", "observedAt": "2026-10-24T06:51:41+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s5b-tail", "name": "s5-control-minimal-end", "sha256": "49873da1ea328db901ffdfe1da3a4143cddd4a2ffc4bf6df462936dac2aebdb5", "observedAt": "2026-10-24T06:51:41+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s6a-s6-ascii-control", "name": "s6-ascii-control", "sha256": "552826505c024774fa6a3830f3331e64629ca257bdbe7e400cfc23d6ec9a8de8", "observedAt": "2026-10-24T06:56:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s6a-s6-cp437-byte-noflag", "name": "s6-cp437-byte-noflag", "sha256": "a4a3ca9d143cc102a6b87b441496ff7ff9d13c816945c522d966076132de55dd", "observedAt": "2026-10-24T06:56:58.981Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__s6-cp437-byte-noflag.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-cp437-byte-noflag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-cp437-byte-noflag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s6a-s6-utf8-bytes-flag", "name": "s6-utf8-bytes-flag", "sha256": "8c537b95b8930a888100f12cd4b7c7c80466696e181cccc7d40cd26bb55645a4", "observedAt": "2026-10-24T06:57:13.156Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__s6-utf8-bytes-flag.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-utf8-bytes-flag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-utf8-bytes-flag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s6a-s6-utf8-bytes-noflag", "name": "s6-utf8-bytes-noflag", "sha256": "df6ea023437e29f761634cc21dda654f90831a12c9241dfff3ec1aa878719745", "observedAt": "2026-10-24T06:57:27.234Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__s6-utf8-bytes-noflag.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-utf8-bytes-noflag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-utf8-bytes-noflag.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s6a-s6-pct-encoded-ascii", "name": "s6-pct-encoded-ascii", "sha256": "55bc366c36cdee2ac5609c6ae6ffc8d847423762dfc4315246037c7ca0f23d04", "observedAt": "2026-10-24T06:57:41.674Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__s6-pct-encoded-ascii.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-pct-encoded-ascii.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-pct-encoded-ascii.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s6b-s6-ascii-control-in-word", "name": "s6-ascii-control-in-word", "sha256": "055d1dbf8ae1d2da3e94fdf0c7f245881b78eed4dfda0f7162e7313465f7353a", "observedAt": "2026-10-24T06:58:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s6b-s6-pct-ascii-space-root", "name": "s6-pct-ascii-space-root", "sha256": "0a7d3a4ea2f152197ab748a468fb305cbd0a695a19b7cd8ee4cf0283caf5fd9e", "observedAt": "2026-10-24T06:58:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s6b-s6-pct-latin1-e9", "name": "s6-pct-latin1-e9", "sha256": "222cab2384ca8eb9620617debbee94e8480113f88fd7865c34e5f6f2c046002f", "observedAt": "2026-10-24T06:58:44.899Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-pct-latin1-e9.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-pct-latin1-e9.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s6b-s6-utf8-flag-in-word", "name": "s6-utf8-flag-in-word", "sha256": "c9317c54a63b0094fa637a6607e3d14080a4069a1473eb3a209ed97a602e2c1b", "observedAt": "2026-10-24T06:59:04.741Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__s6-utf8-flag-in-word.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__s6-utf8-flag-in-word.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
```

</details>

### Session 7: 07:27Z–07:29Z, validator columns at 9960b273 and 34d0ace3

Each specimen is `MINIMAL_PARTS` plus one `<Override PartName="…" ContentType="application/xml"/>` for a part that is not stored. `s7` is one batch of ten. `s7b` observes the folder-dot specimen again in a run of its own, rebuilt (so its hash differs), and `s7c` adds two more spellings of it.

| Run   | Observed  | Specimen                           | Issue   | `PartName`               | SHA-256 (first 16) | Word           | word-valid at 9960b273                                       | word-valid at 34d0ace3                                       | strict at 34d0ace3                                                                                                               |
| ----- | --------- | ---------------------------------- | ------- | ------------------------ | ------------------ | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `s7`  | 07:28:24Z | `s7-control-minimal`               | control | —                        | `93f757b1c393dc0d` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s7`  | 07:28:24Z | `414-xml-plain-missing-control-s7` | #414    | `/word/nothere.xml`      | `5f264eed942ca251` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s7`  | 07:28:21Z | `414-xml-trailing-dot-missing`     | #414    | `/word/nothere.xml.`     | `b89b5b05bda0c7e1` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7`  | 07:28:24Z | `414-xml-folder-dot-missing`       | #450    | `/word./nothere.xml`     | `4f2563f8daaa94f9` | clean-open     | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | valid                                                        | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7`  | 07:28:17Z | `414-xml-space-missing`            | #414    | `/word/no there.xml`     | `c9680496d636f212` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7`  | 07:28:03Z | `414-xml-bracket-missing`          | #414    | `/word/no[there].xml`    | `305a7938f2ef65a0` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s7`  | 07:28:08Z | `414-xml-nonascii-missing`         | #414    | `/word/café.xml`         | `d335fa997869215c` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7`  | 07:28:24Z | `414-xml-pct20-missing-control`    | #414    | `/word/no%20there.xml`   | `c5b1d528dbf83a41` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s7`  | 07:28:13Z | `414-xml-pctC3A9-missing`          | #451    | `/word/caf%C3%A9.xml`    | `ff326e134cf0bb24` | repair-warning | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s7`  | 07:28:24Z | `s7-control-minimal-end`           | control | —                        | `93f757b1c393dc0d` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s7b` | 07:29:07Z | `414-xml-folder-dot-missing`       | #450    | `/word./nothere.xml`     | `4188a0942b9468a4` | clean-open     | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | valid                                                        | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7c` | 07:29:18Z | `414-xml-folder-dot-deep-missing`  | #450    | `/word/sub./nothere.xml` | `406bcf83d752f185` | clean-open     | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | valid                                                        | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s7c` | 07:29:18Z | `414-xml-folder-dot-root-missing`  | #450    | `/x./nothere.xml`        | `32dea02fb35b9d4e` | clean-open     | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | valid                                                        | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |

<details><summary>Raw records, session 7</summary>

```jsonl
{"run": "s7", "name": "s7-control-minimal", "sha256": "93f757b1c393dc0d3533c48736e6e1fe3ceab635d705c530ac6e1126eea185ae", "observedAt": "2026-10-24T07:28:24+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7", "name": "414-xml-plain-missing-control-s7", "sha256": "5f264eed942ca251041e96c420880612651ad2a20e9f3ca1bb47d5716ece1606", "observedAt": "2026-10-24T07:28:24+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7", "name": "414-xml-trailing-dot-missing", "sha256": "b89b5b05bda0c7e12f61c3e1264d59a30b5e5adbaeffce51b8a014b639165f5a", "observedAt": "2026-10-24T07:28:21.784Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__414-xml-trailing-dot-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__414-xml-trailing-dot-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s7", "name": "414-xml-folder-dot-missing", "sha256": "4f2563f8daaa94f9a4edd9d268f286f19c5929d6ebfbe48d838df7ec3f37dd50", "observedAt": "2026-10-24T07:28:24+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7", "name": "414-xml-space-missing", "sha256": "c9680496d636f212e3d563ddcf45005fde1300fab8079c3f005c6db3b3a4e702", "observedAt": "2026-10-24T07:28:17.543Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__414-xml-space-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__414-xml-space-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s7", "name": "414-xml-bracket-missing", "sha256": "305a7938f2ef65a06ea40f93fd12aae52e327edbf9a71f8cf6065f194cb4ef63", "observedAt": "2026-10-24T07:28:03.699Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-xml-bracket-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-xml-bracket-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s7", "name": "414-xml-nonascii-missing", "sha256": "d335fa997869215c4b978686e8e0c2e288b579849fe3260a40c7b039fd3730ec", "observedAt": "2026-10-24T07:28:08.635Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__414-xml-nonascii-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__414-xml-nonascii-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s7", "name": "414-xml-pct20-missing-control", "sha256": "c5b1d528dbf83a41f5e7b5b35a6ba1c8b987801710c8555401fe408537d2aecf", "observedAt": "2026-10-24T07:28:24+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7", "name": "414-xml-pctC3A9-missing", "sha256": "ff326e134cf0bb24eebf1084feced919ba6422f517c5a602fb8f98dbd3033ecb", "observedAt": "2026-10-24T07:28:13.187Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__414-xml-pctC3A9-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__414-xml-pctC3A9-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s7", "name": "s7-control-minimal-end", "sha256": "93f757b1c393dc0d3533c48736e6e1fe3ceab635d705c530ac6e1126eea185ae", "observedAt": "2026-10-24T07:28:24+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7b", "name": "414-xml-folder-dot-missing", "sha256": "4188a0942b9468a498665c7f4f83db655ce9dd4a612e52c5d3357ed267b9eda3", "observedAt": "2026-10-24T07:29:07+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7c", "name": "414-xml-folder-dot-deep-missing", "sha256": "406bcf83d752f1857c72552d3279a532e2f92a96dbc3c95c8443b264a8bebe56", "observedAt": "2026-10-24T07:29:18+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s7c", "name": "414-xml-folder-dot-root-missing", "sha256": "32dea02fb35b9d4ef8fc067613ce89020e1e98915f3c94101f698afaebf3361c", "observedAt": "2026-10-24T07:29:18+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 8: 07:47Z–07:48Z, validator columns at 49922e9a and e08611b1

`s8a` holds the #432 specimens, each part typed only by the generic `Default` beside a control with the part's `Override`, and the #443 specimens, a styles part stored under an `sty` name and typed by an `sty` `Default`. `s8b` holds three #451 `PartName` escapes and the first #437 specimens: a part a known relationship names, cut short at 60 characters, that the document does not use.

| Run   | Observed  | Specimen                                            | Issue   | Shape                                                                         | SHA-256 (first 16) | Word           | word-valid at 49922e9a                                                              | word-valid at e08611b1                                                              | strict at e08611b1                                                                      |
| ----- | --------- | --------------------------------------------------- | ------- | ----------------------------------------------------------------------------- | ------------------ | -------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `s8a` | 07:48:13Z | `s8-control-minimal`                                | control | —                                                                             | `46810497bd9460db` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:13Z | `432-settings-override-control`                     | #432    | settings, with its Override                                                   | `290495461c6eed03` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:47:43Z | `432-settings-generic-default`                      | #432    | settings, generic Default only                                                | `e6226536abba0b74` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:13Z | `432-fonttable-override-control`                    | #432    | fontTable, with its Override                                                  | `b6cf401f8d6d2133` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:47:34Z | `432-fonttable-generic-default`                     | #432    | fontTable, generic Default only                                               | `021808c980c86554` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:13Z | `432-websettings-override-control`                  | #432    | webSettings, with its Override                                                | `7a0f93cfbe407a7e` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:47:51Z | `432-websettings-generic-default`                   | #432    | webSettings, generic Default only                                             | `20861cabaa1ee26a` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:47:38Z | `432-main-generic-default`                          | #432    | main part, its Override removed                                               | `19a10f0abd9b3128` | repair-warning | valid                                                                               | valid                                                                               | invalid (`ct-undeclared-part@word/document.xml`)                                        |
| `s8a` | 07:47:47Z | `432-styles-generic-default-s8`                     | #432    | styles, its Override removed                                                  | `4d0b1c18e4d65438` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:13Z | `443-styles-ascii-sty-control`                      | #443    | styles stored as `word/styles.sty`, target `styles.sty`                       | `5550535e47a76b2f` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:00Z | `443-styles-nonascii-sty-referenced`                | #443    | styles stored as `word/stylés.sty`, target `stylés.sty`                       | `3ba2d65c5cc7cd40` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:47:56Z | `443-styles-nonascii-sty-referenced-escaped-target` | #443    | styles stored as `word/stylés.sty`, target `styl%C3%A9s.sty`                  | `51112f2aedbeedae` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8a` | 07:48:13Z | `s8-control-minimal-mid`                            | control | —                                                                             | `fedb8376980c5fdd` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:40Z | `451-pctE9-missing`                                 | #451    | PartName `/word/caf%E9.xml`                                                   | `fd8f181b1cf4b2a8` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:35Z | `451-pct21-missing`                                 | #451    | PartName `/word/a%21b.xml`                                                    | `19c8dcf487abf041` | repair-warning | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:43Z | `451-pct7F-missing`                                 | #451    | PartName `/word/a%7Fb.xml`                                                    | `6305e7316a2f43bb` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:31Z | `437-customxml-rel-malformed`                       | #437    | `customXml/item1.xml` cut short, named by a document `customXml` relationship | `ffe333cc9de1d00c` | repair-warning | valid                                                                               | valid                                                                               | invalid (`xml-undeclared-prefix@customXml/item1.xml`, `xml-syntax@customXml/item1.xml`) |
| `s8b` | 07:48:43Z | `437-customxml-rel-wellformed-control`              | #437    | `customXml/item1.xml` well formed, same relationship                          | `ff33da2a95a06803` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:43Z | `437-footer-rel-unused-malformed`                   | #437    | footer cut short, related, unused                                             | `50441e689e800c2e` | clean-open     | invalid (`xml-syntax@word/footer1.xml`, `xml-undeclared-prefix@word/footer1.xml`)   | invalid (`xml-syntax@word/footer1.xml`, `xml-undeclared-prefix@word/footer1.xml`)   | invalid (`xml-syntax@word/footer1.xml`, `xml-undeclared-prefix@word/footer1.xml`)       |
| `s8b` | 07:48:43Z | `437-footer-rel-unused-wellformed-control`          | #437    | footer well formed, related, unused                                           | `759e94c307ee14a0` | clean-open     | valid                                                                               | valid                                                                               | invalid (`paraid-missing-element@word/footer1.xml`)                                     |
| `s8b` | 07:48:43Z | `437-comments-rel-malformed`                        | #437    | comments cut short, related, unused                                           | `41dd8af1033dc543` | clean-open     | invalid (`xml-syntax@word/comments.xml`, `xml-undeclared-prefix@word/comments.xml`) | invalid (`xml-syntax@word/comments.xml`, `xml-undeclared-prefix@word/comments.xml`) | invalid (`xml-syntax@word/comments.xml`, `xml-undeclared-prefix@word/comments.xml`)     |
| `s8b` | 07:48:43Z | `437-comments-rel-wellformed-control`               | #437    | comments well formed, related, unused                                         | `f9582ed2398ece00` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |
| `s8b` | 07:48:43Z | `s8-control-minimal-end`                            | control | —                                                                             | `fedb8376980c5fdd` | clean-open     | valid                                                                               | valid                                                                               | valid                                                                                   |

<details><summary>Raw records, session 8</summary>

```jsonl
{"run": "s8a", "name": "s8-control-minimal", "sha256": "46810497bd9460db5aee8c3e5798ad9866c7e84be42c36cce9c99bc195bbf148", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8a", "name": "432-settings-override-control", "sha256": "290495461c6eed035446c24d6ddd9ba5ecdb96c22cbfca8c4d8d39f8babaee64", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8a", "name": "432-settings-generic-default", "sha256": "e6226536abba0b74f734f95ecaa474a571bb9e4c7900e228aedfe0b37a6b62a5", "observedAt": "2026-10-24T07:47:43.381Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__432-settings-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__432-settings-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "432-fonttable-override-control", "sha256": "b6cf401f8d6d2133ed350e314b0ae319d502845f66a3f55f324b74c569b3ec19", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8a", "name": "432-fonttable-generic-default", "sha256": "021808c980c86554535da2c7253c98f83e8bf4fb7839924d4df78bae1e79fe7a", "observedAt": "2026-10-24T07:47:34.165Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__432-fonttable-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__432-fonttable-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "432-websettings-override-control", "sha256": "7a0f93cfbe407a7e6700b0c2f604e784b3d24ed243c4cd765d6670ce527127b5", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8a", "name": "432-websettings-generic-default", "sha256": "20861cabaa1ee26a4523e4889562d94cb85627e9526770e5ff7030cc1fe04559", "observedAt": "2026-10-24T07:47:51.831Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__432-websettings-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__432-websettings-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "432-main-generic-default", "sha256": "19a10f0abd9b3128a89f08ddb8f40d1e938cdc58e043d75f171aeece959866e9", "observedAt": "2026-10-24T07:47:38.914Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__432-main-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__432-main-generic-default.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "432-styles-generic-default-s8", "sha256": "4d0b1c18e4d65438965b358347925a431d1bb312af666896d931cbe430bd9267", "observedAt": "2026-10-24T07:47:47.616Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__432-styles-generic-default-s8.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__432-styles-generic-default-s8.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "443-styles-ascii-sty-control", "sha256": "5550535e47a76b2f4dbd8e5c4468a1452f64978d516b44991a5d483062087010", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8a", "name": "443-styles-nonascii-sty-referenced", "sha256": "3ba2d65c5cc7cd40d995a67a6fca06e60afbc604f46e0fa4d85032aef71fc1bc", "observedAt": "2026-10-24T07:48:00.431Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00010__wfv__443-styles-nonascii-sty-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00010__wfv__443-styles-nonascii-sty-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "443-styles-nonascii-sty-referenced-escaped-target", "sha256": "51112f2aedbeedaea3e4cb26d3dd38a6029112677648808ecf750e8bc9ef85eb", "observedAt": "2026-10-24T07:47:56.230Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00009__wfv__443-styles-nonascii-sty-referenced-escaped-target.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00009__wfv__443-styles-nonascii-sty-referenced-escaped-targe.... Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00009__wfv__443-styles-nonascii-sty-referenced-escaped-targe.... Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8a", "name": "s8-control-minimal-mid", "sha256": "fedb8376980c5fdd522371f9b407bc7cc9e9a96461fc2fbc543e5c2dd37ed86b", "observedAt": "2026-10-24T07:48:13+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "451-pctE9-missing", "sha256": "fd8f181b1cf4b2a8a714c5ba5d200accd46da6e88fd0acdb2490965e5d3c3768", "observedAt": "2026-10-24T07:48:40.047Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00008__wfv__451-pctE9-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00008__wfv__451-pctE9-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8b", "name": "451-pct21-missing", "sha256": "19c8dcf487abf0417cced1e6ca8776ce9c11e9ede8c5f1f003962bff48505257", "observedAt": "2026-10-24T07:48:35.681Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__451-pct21-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__451-pct21-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8b", "name": "451-pct7F-missing", "sha256": "6305e7316a2f43bb2e06ba45aaa8ca79345b3ee13ce541c575a3c0658e787141", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "437-customxml-rel-malformed", "sha256": "ffe333cc9de1d00c991a8e5f76d9e6584f260d0e31a0f18db5076d7145187809", "observedAt": "2026-10-24T07:48:31.147Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__437-customxml-rel-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__437-customxml-rel-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s8b", "name": "437-customxml-rel-wellformed-control", "sha256": "ff33da2a95a0680355a68ec07ce28588b1923ddebdc0ef1c93def1714c5f4aa2", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "437-footer-rel-unused-malformed", "sha256": "50441e689e800c2ef635c8e4b7ba0efd1d7881b4b410b5e9794538c07a570e6e", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "437-footer-rel-unused-wellformed-control", "sha256": "759e94c307ee14a034c84687df612be4962cbb46ab474e505b5086dcb86b1606", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "437-comments-rel-malformed", "sha256": "41dd8af1033dc543f488999581b0d112521010e8c09344c20612d9855cd95c8a", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "437-comments-rel-wellformed-control", "sha256": "f9582ed2398ece002cfee15109c7e52f04c2a86af32d202c2fcd2a75440f26c8", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s8b", "name": "s8-control-minimal-end", "sha256": "fedb8376980c5fdd522371f9b407bc7cc9e9a96461fc2fbc543e5c2dd37ed86b", "observedAt": "2026-10-24T07:48:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 9: 07:50Z–07:51Z, validator columns at 49922e9a and e08611b1

`s9a` refines #437: a part is unclosed (well formed up to the missing end tag of its root), and either the main part uses it (`w:footerReference`, or a comment range with its `w:commentReference`) or only a relationship names it. `s9b` adds `PartName` escapes of characters `pchar` allows or must escape (#451), and the same question for an unreferenced stored name (#408).

| Run   | Observed  | Specimen                                          | Issue   | Shape                                            | SHA-256 (first 16) | Word           | word-valid at 49922e9a                      | word-valid at e08611b1                      | strict at e08611b1                                                                                     |
| ----- | --------- | ------------------------------------------------- | ------- | ------------------------------------------------ | ------------------ | -------------- | ------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `s9a` | 07:50:46Z | `s9-control-minimal`                              | control | —                                                | `a049b8c3728051a2` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9a` | 07:50:21Z | `437-footer-referenced-malformed`                 | #437    | footer unclosed, referenced from `w:sectPr`      | `1e46f550b21f61e0` | open-error     | invalid (`xml-syntax@word/footer1.xml`)     | invalid (`xml-syntax@word/footer1.xml`)     | invalid (`xml-syntax@word/footer1.xml`)                                                                |
| `s9a` | 07:50:46Z | `437-footer-referenced-wellformed-control`        | #437    | footer well formed, referenced                   | `ee876d5b9790a599` | clean-open     | valid                                       | valid                                       | invalid (`paraid-missing-element@word/footer1.xml`)                                                    |
| `s9a` | 07:50:46Z | `437-footer-related-unused-unclosed`              | #437    | footer unclosed, related, unused                 | `27b063df97baf2ed` | clean-open     | invalid (`xml-syntax@word/footer1.xml`)     | invalid (`xml-syntax@word/footer1.xml`)     | invalid (`xml-syntax@word/footer1.xml`)                                                                |
| `s9a` | 07:50:10Z | `437-comments-referenced-malformed`               | #437    | comments unclosed, referenced by a comment range | `bb4e04eee5069bca` | repair-warning | invalid (`xml-syntax@word/comments.xml`)    | invalid (`xml-syntax@word/comments.xml`)    | invalid (`xml-syntax@word/comments.xml`)                                                               |
| `s9a` | 07:50:46Z | `437-comments-referenced-wellformed-control`      | #437    | comments well formed, referenced                 | `523a442c9bbea652` | clean-open     | valid                                       | valid                                       | invalid (`paraid-missing-element@word/comments.xml`)                                                   |
| `s9a` | 07:50:46Z | `437-comments-related-unused-unclosed`            | #437    | comments unclosed, related, unused               | `7925f9c273890a4a` | clean-open     | invalid (`xml-syntax@word/comments.xml`)    | invalid (`xml-syntax@word/comments.xml`)    | invalid (`xml-syntax@word/comments.xml`)                                                               |
| `s9a` | 07:50:29Z | `437-settings-malformed`                          | #437    | settings unclosed, related                       | `79463625b6d8de3e` | repair-warning | invalid (`xml-syntax@word/settings.xml`)    | invalid (`xml-syntax@word/settings.xml`)    | invalid (`xml-syntax@word/settings.xml`)                                                               |
| `s9a` | 07:50:16Z | `437-fonttable-malformed`                         | #437    | fontTable unclosed, related                      | `5307f68df2dfc6ff` | repair-warning | invalid (`xml-syntax@word/fontTable.xml`)   | invalid (`xml-syntax@word/fontTable.xml`)   | invalid (`xml-syntax@word/fontTable.xml`)                                                              |
| `s9a` | 07:50:34Z | `437-websettings-malformed`                       | #437    | webSettings unclosed, related                    | `aebc2cbcc8962a91` | repair-warning | invalid (`xml-syntax@word/webSettings.xml`) | invalid (`xml-syntax@word/webSettings.xml`) | invalid (`xml-syntax@word/webSettings.xml`)                                                            |
| `s9a` | 07:50:25Z | `437-numbering-related-unused-malformed`          | #437    | numbering unclosed, related, unused              | `23061d78523eb59d` | repair-warning | invalid (`xml-syntax@word/numbering.xml`)   | invalid (`xml-syntax@word/numbering.xml`)   | invalid (`xml-syntax@word/numbering.xml`)                                                              |
| `s9a` | 07:50:46Z | `437-footnotes-related-unused-malformed`          | #437    | footnotes unclosed, related, unused              | `463f0a0a4d19dd12` | clean-open     | invalid (`xml-syntax@word/footnotes.xml`)   | invalid (`xml-syntax@word/footnotes.xml`)   | invalid (`xml-syntax@word/footnotes.xml`)                                                              |
| `s9a` | 07:50:46Z | `437-footnotes-related-unused-wellformed-control` | #437    | footnotes well formed, related, unused           | `d3ba5608b0635adc` | clean-open     | valid                                       | valid                                       | invalid (`paraid-missing-element@word/footnotes.xml`)                                                  |
| `s9a` | 07:50:46Z | `s9-control-minimal-mid`                          | control | —                                                | `28099e0b39b20885` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct3A-missing`                               | #451    | PartName `/word/a%3Ab.xml`                       | `b8833b6534ef77a9` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct40-missing`                               | #451    | PartName `/word/a%40b.xml`                       | `37e8941c0b1c5787` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct24-missing`                               | #451    | PartName `/word/a%24b.xml`                       | `868d63304b00a462` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct3D-missing`                               | #451    | PartName `/word/a%3Db.xml`                       | `16dec5471b55d0ed` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct2C-missing`                               | #451    | PartName `/word/a%2Cb.xml`                       | `5d1b5e338a4fbecd` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct25-missing`                               | #451    | PartName `/word/a%25b.xml`                       | `51c3acf6af880f11` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct22-missing`                               | #451    | PartName `/word/a%22b.xml`                       | `d35fc880d0ba3c1b` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct5B-missing`                               | #451    | PartName `/word/a%5Bb.xml`                       | `e5e0010392c4f809` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct7B-missing`                               | #451    | PartName `/word/a%7Bb.xml`                       | `606bf8dca7a22857` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:21Z | `451-pct3C-missing`                               | #451    | PartName `/word/a%3Cb.xml`                       | `8011b9817ba01cce` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |
| `s9b` | 07:51:15Z | `408-stored-pct21-unreferenced`                   | #408    | stored `word/a%21b.xml`                          | `aa0376d091e0f36a` | repair-warning | valid                                       | valid                                       | invalid (`rels-unreferenced@word/a%21b.xml`, `xsd-summary@word/a%21b.xml`, `xsd-error@word/a%21b.xml`) |
| `s9b` | 07:51:21Z | `408-stored-pct3A-unreferenced`                   | #408    | stored `word/a%3Ab.xml`                          | `0f5952f7a66211a7` | clean-open     | valid                                       | valid                                       | invalid (`rels-unreferenced@word/a%3Ab.xml`, `xsd-summary@word/a%3Ab.xml`, `xsd-error@word/a%3Ab.xml`) |
| `s9b` | 07:51:21Z | `408-stored-pct5B-unreferenced`                   | #408    | stored `word/a%5Bb.xml`                          | `b7ab9026872731e4` | clean-open     | valid                                       | valid                                       | invalid (`rels-unreferenced@word/a%5Bb.xml`, `xsd-summary@word/a%5Bb.xml`, `xsd-error@word/a%5Bb.xml`) |
| `s9b` | 07:51:21Z | `408-stored-pct7F-unreferenced`                   | #408    | stored `word/a%7Fb.xml`                          | `60745fbbf35bbb56` | clean-open     | valid                                       | valid                                       | invalid (`rels-unreferenced@word/a%7Fb.xml`, `xsd-summary@word/a%7Fb.xml`, `xsd-error@word/a%7Fb.xml`) |
| `s9b` | 07:51:21Z | `s9-control-minimal-end`                          | control | —                                                | `405ce71c9287e93e` | clean-open     | valid                                       | valid                                       | valid                                                                                                  |

<details><summary>Raw records, session 9</summary>

```jsonl
{"run": "s9a", "name": "s9-control-minimal", "sha256": "a049b8c3728051a2f064591c5af56c4d36aa697af451509cbedef805848eda81", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-footer-referenced-malformed", "sha256": "1e46f550b21f61e0cb31edeaa6f3e57783d190137c28221258b519dfe316246e", "observedAt": "2026-10-24T07:50:21.332Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__437-footer-referenced-malformed.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-footer-referenced-wellformed-control", "sha256": "ee876d5b9790a599005ebb9b0d6fdd684a7c142107f16b670c08c5b6565e9bfd", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-footer-related-unused-unclosed", "sha256": "27b063df97baf2ed8174636ca41601f7dc3499bed0ad0da5b835194eef5a65c4", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-comments-referenced-malformed", "sha256": "bb4e04eee5069bca6e06ef8245fdb29a491cadb7391ec960b5cb54e2bae298ed", "observedAt": "2026-10-24T07:50:10.747Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__437-comments-referenced-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__437-comments-referenced-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-comments-referenced-wellformed-control", "sha256": "523a442c9bbea652b31b36c8519336e450c6b2e12f3b2fd95bcd9bcda25f7ab9", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-comments-related-unused-unclosed", "sha256": "7925f9c273890a4ac2a3e735f8e9e3444a952159c4e240855bdfdaf3aeaf821b", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-settings-malformed", "sha256": "79463625b6d8de3e03a087d7c21882e1c49db24f51ca54c72b52729d5a2357a7", "observedAt": "2026-10-24T07:50:29.882Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00010__wfv__437-settings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00010__wfv__437-settings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-fonttable-malformed", "sha256": "5307f68df2dfc6ffa44c8f2a46a09ffe9476a439fd159d36a2d0ff5c4d68f69c", "observedAt": "2026-10-24T07:50:16.897Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__437-fonttable-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__437-fonttable-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-websettings-malformed", "sha256": "aebc2cbcc8962a91c406b93c5d2aa7d5c3bf53753deadc92282b5e642b806d25", "observedAt": "2026-10-24T07:50:34.730Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00011__wfv__437-websettings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00011__wfv__437-websettings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-numbering-related-unused-malformed", "sha256": "23061d78523eb59d9997f37f2f45d702147304affcb4de73ea5cf55629d320a8", "observedAt": "2026-10-24T07:50:25.632Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00009__wfv__437-numbering-related-unused-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00009__wfv__437-numbering-related-unused-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9a", "name": "437-footnotes-related-unused-malformed", "sha256": "463f0a0a4d19dd12ffbf11bb668a9d4a69fa59ce5ea6186c602558f42f785eaf", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "437-footnotes-related-unused-wellformed-control", "sha256": "d3ba5608b0635adc786de053283435bb674aa2186a873d09248b0ae8c6c8575c", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9a", "name": "s9-control-minimal-mid", "sha256": "28099e0b39b20885ee1bb1de1df4f33e5b63f99e2eca6e9fc76714296daad1c3", "observedAt": "2026-10-24T07:50:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct3A-missing", "sha256": "b8833b6534ef77a9d03c2a2880ee1381a68812278c99936e19845a3dea5f4b8a", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct40-missing", "sha256": "37e8941c0b1c57879cab8062126b5c57ba2b55990ec9bc5ec663abbb2a37cf8d", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct24-missing", "sha256": "868d63304b00a462ca4fe400bb5d9c21d57e07c5b4eb9ac6138ca7676051e0cb", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct3D-missing", "sha256": "16dec5471b55d0ed3eb41c2a96464a3f19fa49232c0325af641aafafdbca72f5", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct2C-missing", "sha256": "5d1b5e338a4fbecd81f79071fe45ef528be93c9e73ef8b0b8128fe5ede9d9229", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct25-missing", "sha256": "51c3acf6af880f11aef14505bf1d03e62863dfed7c47ab2a64497e74420e8619", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct22-missing", "sha256": "d35fc880d0ba3c1b5e461a76a9a1096ff76210a45de2390c908a1ed5f0a39236", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct5B-missing", "sha256": "e5e0010392c4f8095a8b3df51630151ff96167a76e106bc799dff88ae0deb302", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct7B-missing", "sha256": "606bf8dca7a228578a8d5cebc8f571b3122c5b07f34d9fc846e81d6d9a9d159f", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "451-pct3C-missing", "sha256": "8011b9817ba01ccee58ba4b2325d0bbcb35aa282131b0fddc2acd3b8a1fac240", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "408-stored-pct21-unreferenced", "sha256": "aa0376d091e0f36a1f3869fc0cb9d5b978b2f660cf85c09dda32726fad5287b2", "observedAt": "2026-10-24T07:51:15.147Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__408-stored-pct21-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__408-stored-pct21-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s9b", "name": "408-stored-pct3A-unreferenced", "sha256": "0f5952f7a66211a71c1629cc7c05f442c7c12aad139dc125756bb7c62c211cd8", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "408-stored-pct5B-unreferenced", "sha256": "b7ab9026872731e423d71f21990d1f079e2f79a04575c5e0f67ce56f1d8aa7a7", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "408-stored-pct7F-unreferenced", "sha256": "60745fbbf35bbb56fff9afd8c578056d80fdf5aa11c913060876ec5e005ff287", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s9b", "name": "s9-control-minimal-end", "sha256": "405ce71c9287e93e80c95bc6708872c8decfe8d2d4f8392db17058a1182520ba", "observedAt": "2026-10-24T07:51:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 10: 07:53Z–07:53Z, validator columns at 49922e9a and e08611b1

A literal `!` in a `PartName` and in a stored name, and the remaining sub-delim escapes in a `PartName` (#451, #408).

| Run   | Observed  | Specimen                               | Issue   | Shape                      | SHA-256 (first 16) | Word           | word-valid at 49922e9a | word-valid at e08611b1 | strict at e08611b1                                                                               |
| ----- | --------- | -------------------------------------- | ------- | -------------------------- | ------------------ | -------------- | ---------------------- | ---------------------- | ------------------------------------------------------------------------------------------------ |
| `s10` | 07:53:28Z | `s10-control-minimal`                  | control | —                          | `c7732ed7987bc4a0` | clean-open     | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:28Z | `451-literal-bang-missing`             | #451    | PartName `/word/a!b.xml`   | `dd1e3ac69b023367` | clean-open     | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:28Z | `408-stored-literal-bang-unreferenced` | #408    | stored `word/a!b.xml`      | `ce1b1521753d2a06` | clean-open     | valid                  | valid                  | invalid (`rels-unreferenced@word/a!b.xml`, `xsd-summary@word/a!b.xml`, `xsd-error@word/a!b.xml`) |
| `s10` | 07:53:28Z | `451-pct26-missing`                    | #451    | PartName `/word/a%26b.xml` | `e436858beeb2969a` | clean-open     | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:12Z | `451-pct27-missing`                    | #451    | PartName `/word/a%27b.xml` | `824e384292b8d734` | repair-warning | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:16Z | `451-pct28-missing`                    | #451    | PartName `/word/a%28b.xml` | `d8a75a99731ed004` | repair-warning | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:20Z | `451-pct29-missing`                    | #451    | PartName `/word/a%29b.xml` | `8b68495352e86d95` | repair-warning | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:24Z | `451-pct2A-missing`                    | #451    | PartName `/word/a%2Ab.xml` | `92aa4bc8f90e11d8` | repair-warning | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:28Z | `451-pct2B-missing`                    | #451    | PartName `/word/a%2Bb.xml` | `8746635cb43cc3d6` | clean-open     | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:28Z | `451-pct3B-missing`                    | #451    | PartName `/word/a%3Bb.xml` | `7e9e56d9d91b2d97` | clean-open     | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:05Z | `451-pct21-lower-missing-s10`          | #451    | PartName `/word/a%21b.xml` | `bc425c72ef356fd1` | repair-warning | valid                  | valid                  | valid                                                                                            |
| `s10` | 07:53:28Z | `s10-control-minimal-end`              | control | —                          | `c7732ed7987bc4a0` | clean-open     | valid                  | valid                  | valid                                                                                            |

<details><summary>Raw records, session 10</summary>

```jsonl
{"run": "s10", "name": "s10-control-minimal", "sha256": "c7732ed7987bc4a0244cd68be1ec0a47f56ca2a8e774696b5af126d3e75830d6", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "451-literal-bang-missing", "sha256": "dd1e3ac69b023367579f0094f542aed44781fd15ee9ab140c29f1e312a0786dd", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "408-stored-literal-bang-unreferenced", "sha256": "ce1b1521753d2a0602b8d9a39b652187cfd4ccf0ffa3467e9e1de8afe24cf0c4", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "451-pct26-missing", "sha256": "e436858beeb2969acfe31d4a9deed3dfc50bf52524216fc9ed604e51d6a5bd55", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "451-pct27-missing", "sha256": "824e384292b8d7349fa596bd7d1c9e55264dc765b221240dab4a6937c882fecb", "observedAt": "2026-10-24T07:53:12.032Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__451-pct27-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__451-pct27-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s10", "name": "451-pct28-missing", "sha256": "d8a75a99731ed004f68d31b42bec8cdbdd3a5ca2c9e9f46b734c79eb12937380", "observedAt": "2026-10-24T07:53:16.315Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__451-pct28-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__451-pct28-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s10", "name": "451-pct29-missing", "sha256": "8b68495352e86d95f058b9624cef6e71adacb13d538e2ebfa9edc2b9475c0c0e", "observedAt": "2026-10-24T07:53:20.532Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__451-pct29-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__451-pct29-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s10", "name": "451-pct2A-missing", "sha256": "92aa4bc8f90e11d8ffb396b680881ae255be7ea2c966acc77d1a6034ae49e48e", "observedAt": "2026-10-24T07:53:24.781Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__451-pct2A-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__451-pct2A-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s10", "name": "451-pct2B-missing", "sha256": "8746635cb43cc3d6edc79c5b00c4dcf6ad448d53690c73c10ea386ab22369cf6", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "451-pct3B-missing", "sha256": "7e9e56d9d91b2d972ec5d238217877dbdf958f25ed207b3ae465692fa0533b16", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s10", "name": "451-pct21-lower-missing-s10", "sha256": "bc425c72ef356fd12aeedac0ee85b5db926aca7add11d94f7ffcb6b7c5c8e7ba", "observedAt": "2026-10-24T07:53:05.600Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__451-pct21-lower-missing-s10.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__451-pct21-lower-missing-s10.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s10", "name": "s10-control-minimal-end", "sha256": "c7732ed7987bc4a0244cd68be1ec0a47f56ca2a8e774696b5af126d3e75830d6", "observedAt": "2026-10-24T07:53:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 11: 07:54Z–07:55Z, validator columns at 49922e9a and e08611b1

The rest of RFC 3986 unreserved, a lower-case hex escape, and escapes of a control character and of 0x80 and above, in a `PartName` (#451); escaped marks and `%26` in a stored name (#408).

| Run   | Observed  | Specimen                        | Issue   | Shape                      | SHA-256 (first 16) | Word           | word-valid at 49922e9a                                       | word-valid at e08611b1                                       | strict at e08611b1                                                                                                                                        |
| ----- | --------- | ------------------------------- | ------- | -------------------------- | ------------------ | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s11` | 07:55:52Z | `s11-control-minimal`           | control | —                          | `53163af036d64a84` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                                                     |
| `s11` | 07:55:11Z | `451-pct7E-missing`             | #451    | PartName `/word/a%7Eb.xml` | `acbed2561facd207` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:54:36Z | `451-pct2D-missing`             | #451    | PartName `/word/a%2Db.xml` | `0501fb0893852039` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:55:02Z | `451-pct5F-missing`             | #451    | PartName `/word/a%5Fb.xml` | `a44d0c276a13f9ec` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:54:40Z | `451-pct2E-missing`             | #451    | PartName `/word/a%2Eb.xml` | `a03c2469b41a5daf` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:54:55Z | `451-pct41-missing`             | #451    | PartName `/word/a%41b.xml` | `34adb1a13c250126` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:54:49Z | `451-pct39-missing`             | #451    | PartName `/word/a%39b.xml` | `996d76fa1bbf2267` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                                              |
| `s11` | 07:54:45Z | `451-pct2a-lower-missing`       | #451    | PartName `/word/a%2ab.xml` | `a9e7527399436038` | repair-warning | valid                                                        | valid                                                        | valid                                                                                                                                                     |
| `s11` | 07:55:52Z | `451-pct01-missing`             | #451    | PartName `/word/a%01b.xml` | `7e8ea9c43ca23fb2` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                                                     |
| `s11` | 07:55:21Z | `451-pct80-missing`             | #451    | PartName `/word/a%80b.xml` | `fdc646d616138256` | repair-warning | valid                                                        | valid                                                        | valid                                                                                                                                                     |
| `s11` | 07:55:48Z | `451-pctFF-missing`             | #451    | PartName `/word/a%FFb.xml` | `b63c05d234a13a20` | repair-warning | valid                                                        | valid                                                        | valid                                                                                                                                                     |
| `s11` | 07:54:12Z | `408-stored-pct27-unreferenced` | #408    | stored `word/a%27b.xml`    | `a113152e33aa074d` | repair-warning | valid                                                        | valid                                                        | invalid (`rels-unreferenced@word/a%27b.xml`, `xsd-summary@word/a%27b.xml`, `xsd-error@word/a%27b.xml`)                                                    |
| `s11` | 07:54:16Z | `408-stored-pct2A-unreferenced` | #408    | stored `word/a%2Ab.xml`    | `9f76d2aefa321d9c` | repair-warning | valid                                                        | valid                                                        | invalid (`rels-unreferenced@word/a%2Ab.xml`, `xsd-summary@word/a%2Ab.xml`, `xsd-error@word/a%2Ab.xml`)                                                    |
| `s11` | 07:54:21Z | `408-stored-pct7E-unreferenced` | #408    | stored `word/a%7Eb.xml`    | `fdeee9d61e8b2aed` | repair-warning | invalid (`opc-part-name-escaped-unreserved@word/a%7Eb.xml`)  | invalid (`opc-part-name-escaped-unreserved@word/a%7Eb.xml`)  | invalid (`rels-unreferenced@word/a%7Eb.xml`, `xsd-summary@word/a%7Eb.xml`, `xsd-error@word/a%7Eb.xml`, `opc-part-name-escaped-unreserved@word/a%7Eb.xml`) |
| `s11` | 07:55:52Z | `408-stored-pct26-unreferenced` | #408    | stored `word/a%26b.xml`    | `5ed13af95979c1ea` | clean-open     | valid                                                        | valid                                                        | invalid (`rels-unreferenced@word/a%26b.xml`, `xsd-summary@word/a%26b.xml`, `xsd-error@word/a%26b.xml`)                                                    |
| `s11` | 07:55:52Z | `s11-control-minimal-end`       | control | —                          | `e01fcf79ebd6259e` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                                                     |

<details><summary>Raw records, session 11</summary>

```jsonl
{"run": "s11", "name": "s11-control-minimal", "sha256": "53163af036d64a842440770a355603d992e70f548bc248b12a9cb03d54b111b3", "observedAt": "2026-10-24T07:55:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s11", "name": "451-pct7E-missing", "sha256": "acbed2561facd20736090027516d5682cb749bc6aa4c978d56222496e190cb23", "observedAt": "2026-10-24T07:55:11.950Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00011__wfv__451-pct7E-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00011__wfv__451-pct7E-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct2D-missing", "sha256": "0501fb089385203918237042cc586a434b9fbe2fa969e8e834e5b96896300dad", "observedAt": "2026-10-24T07:54:36.414Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__451-pct2D-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__451-pct2D-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct5F-missing", "sha256": "a44d0c276a13f9ecdbc1c10f7a032e827a04fdf4f2a0943a22998c3debb5d71b", "observedAt": "2026-10-24T07:55:02.919Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00010__wfv__451-pct5F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00010__wfv__451-pct5F-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct2E-missing", "sha256": "a03c2469b41a5daf17ee857a52022edd666a1271a83cb3dfa4277394431fd281", "observedAt": "2026-10-24T07:54:40.665Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__451-pct2E-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__451-pct2E-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct41-missing", "sha256": "34adb1a13c250126ea61911601ee95a6c7253fe444dd37a52161b915cf8350a2", "observedAt": "2026-10-24T07:54:55.705Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00009__wfv__451-pct41-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00009__wfv__451-pct41-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct39-missing", "sha256": "996d76fa1bbf2267a90993f61122d2123ba2c9f52677a590d150a3d818fd320d", "observedAt": "2026-10-24T07:54:49.515Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00008__wfv__451-pct39-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00008__wfv__451-pct39-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct2a-lower-missing", "sha256": "a9e752739943603817b5a7a070e0aaf2c79ecdd212df079cac0636ccb67f7487", "observedAt": "2026-10-24T07:54:45.048Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__451-pct2a-lower-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__451-pct2a-lower-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pct01-missing", "sha256": "7e8ea9c43ca23fb21f7effb7571fc3707c86dbf4d366ea3767ac5331b45de319", "observedAt": "2026-10-24T07:55:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s11", "name": "451-pct80-missing", "sha256": "fdc646d616138256905b8c0df22a776b4aa907eb4bcaff10d861f72c83fc9c92", "observedAt": "2026-10-24T07:55:21.583Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00012__wfv__451-pct80-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00012__wfv__451-pct80-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "451-pctFF-missing", "sha256": "b63c05d234a13a200d7bf55a205c7351adb6fe3aad6999bd0c854ff334add22a", "observedAt": "2026-10-24T07:55:48.635Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00013__wfv__451-pctFF-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s11", "name": "408-stored-pct27-unreferenced", "sha256": "a113152e33aa074d56db5ff8511badc9dcb6acc5878072c60c7bdea518f2f1e5", "observedAt": "2026-10-24T07:54:12.448Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__408-stored-pct27-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__408-stored-pct27-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "408-stored-pct2A-unreferenced", "sha256": "9f76d2aefa321d9c65ffa121571a25429b02af69201dae38085ca03ba299ffba", "observedAt": "2026-10-24T07:54:16.865Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__408-stored-pct2A-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__408-stored-pct2A-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "408-stored-pct7E-unreferenced", "sha256": "fdeee9d61e8b2aed07ab272236165080991f0c2bf335b09a23fcadcc2da6d02f", "observedAt": "2026-10-24T07:54:21.098Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__408-stored-pct7E-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__408-stored-pct7E-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s11", "name": "408-stored-pct26-unreferenced", "sha256": "5ed13af95979c1ea517def7e5040c5d86226aad6e5af324431c477882efc36bc", "observedAt": "2026-10-24T07:55:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s11", "name": "s11-control-minimal-end", "sha256": "e01fcf79ebd6259e468e88793e337a30a008ab632969ae53f31914aa020aaf4b", "observedAt": "2026-10-24T07:55:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 12: 07:59Z–07:59Z, validator columns at 49922e9a and e08611b1

Dot-only folder segments (review AB S1, #453) beside the `/word./` control, and the remaining stored-name escapes (#408, #443).

| Run   | Observed  | Specimen                          | Issue   | Shape                       | SHA-256 (first 16) | Word           | word-valid at 49922e9a | word-valid at e08611b1                                       | strict at e08611b1                                                                                                 |
| ----- | --------- | --------------------------------- | ------- | --------------------------- | ------------------ | -------------- | ---------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `s12` | 07:59:32Z | `s12-control-minimal`             | control | —                           | `3b71442f26c56f74` | clean-open     | valid                  | valid                                                        | valid                                                                                                              |
| `s12` | 07:59:24Z | `450-dots3-folder-missing`        | #450    | PartName `/word/.../x.xml`  | `af92d93d2a9d0e7f` | repair-warning | valid                  | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                       |
| `s12` | 07:59:28Z | `450-dots4-folder-missing`        | #450    | PartName `/word/..../x.xml` | `8bf865972a81d79c` | repair-warning | valid                  | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                       |
| `s12` | 07:59:20Z | `450-dots3-first-folder-missing`  | #450    | PartName `/.../x.xml`       | `e0392d61bdbf078e` | repair-warning | valid                  | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                       |
| `s12` | 07:59:32Z | `450-word-dot-folder-control-s12` | #450    | PartName `/word./x.xml`     | `0ac5be98685f79b2` | clean-open     | valid                  | valid                                                        | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                       |
| `s12` | 07:59:03Z | `408-stored-pct28-unreferenced`   | #408    | stored `word/a%28b.xml`     | `f15b362a047c7556` | repair-warning | valid                  | valid                                                        | invalid (`rels-unreferenced@word/a%28b.xml`, `xsd-summary@word/a%28b.xml`, `xsd-error@word/a%28b.xml`)             |
| `s12` | 07:59:07Z | `408-stored-pct29-unreferenced`   | #408    | stored `word/a%29b.xml`     | `34bab3a959338131` | repair-warning | valid                  | valid                                                        | invalid (`rels-unreferenced@word/a%29b.xml`, `xsd-summary@word/a%29b.xml`, `xsd-error@word/a%29b.xml`)             |
| `s12` | 07:59:15Z | `408-stored-pctC3A9-unreferenced` | #408    | stored `word/caf%C3%A9.xml` | `b1c81bade2fa92f7` | repair-warning | valid                  | valid                                                        | invalid (`rels-unreferenced@word/caf%C3%A9.xml`, `xsd-summary@word/caf%C3%A9.xml`, `xsd-error@word/caf%C3%A9.xml`) |
| `s12` | 07:59:11Z | `408-stored-pct80-unreferenced`   | #408    | stored `word/a%80b.xml`     | `e000f0f61f8e45f1` | repair-warning | valid                  | valid                                                        | invalid (`rels-unreferenced@word/a%80b.xml`, `xsd-summary@word/a%80b.xml`, `xsd-error@word/a%80b.xml`)             |
| `s12` | 07:59:32Z | `s12-control-minimal-end`         | control | —                           | `3b71442f26c56f74` | clean-open     | valid                  | valid                                                        | valid                                                                                                              |

<details><summary>Raw records, session 12</summary>

```jsonl
{"run": "s12", "name": "s12-control-minimal", "sha256": "3b71442f26c56f74c40cd673feae668c41cf8498f52d7561bf62822a90a97afd", "observedAt": "2026-10-24T07:59:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s12", "name": "450-dots3-folder-missing", "sha256": "af92d93d2a9d0e7f36ce278dbea3e3b2932651ee2c834bd49e31dbb664bcafc6", "observedAt": "2026-10-24T07:59:24.259Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__450-dots3-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__450-dots3-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "450-dots4-folder-missing", "sha256": "8bf865972a81d79cf3a56a23e891044362c69c5168f916aea2eae3173642c361", "observedAt": "2026-10-24T07:59:28.493Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__450-dots4-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__450-dots4-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "450-dots3-first-folder-missing", "sha256": "e0392d61bdbf078e5d893e72016605de8f095a0fa9d403c131a3405c57ffca74", "observedAt": "2026-10-24T07:59:20.058Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__450-dots3-first-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__450-dots3-first-folder-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "450-word-dot-folder-control-s12", "sha256": "0ac5be98685f79b2608a5604b24cf9bf750f77282cb7876514a329264a2872e6", "observedAt": "2026-10-24T07:59:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s12", "name": "408-stored-pct28-unreferenced", "sha256": "f15b362a047c75561f3d8da2440300bb3b7f9854253d30942f3b2305f4869a09", "observedAt": "2026-10-24T07:59:03.027Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__408-stored-pct28-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__408-stored-pct28-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "408-stored-pct29-unreferenced", "sha256": "34bab3a9593381317261b90fb377a7978620e13a92ebbe6bca15e66205cf1338", "observedAt": "2026-10-24T07:59:07.301Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__408-stored-pct29-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__408-stored-pct29-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "408-stored-pctC3A9-unreferenced", "sha256": "b1c81bade2fa92f756cd51a700f1356d3fbc02d85aa75c0641c290dff77b3863", "observedAt": "2026-10-24T07:59:15.832Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__408-stored-pctC3A9-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__408-stored-pctC3A9-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "408-stored-pct80-unreferenced", "sha256": "e000f0f61f8e45f190d585258fe1b529663dfbd7a66551f064a4b6be2ec07c9a", "observedAt": "2026-10-24T07:59:11.556Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__408-stored-pct80-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__408-stored-pct80-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s12", "name": "s12-control-minimal-end", "sha256": "3b71442f26c56f74c40cd673feae668c41cf8498f52d7561bf62822a90a97afd", "observedAt": "2026-10-24T07:59:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 13: 08:04Z–08:04Z, validator columns at 49922e9a and e08611b1

An `Override` without a `PartName`, with an empty one and with `/` alone (review AA S2, #458).

| Run   | Observed  | Specimen                      | Issue   | Shape                           | SHA-256 (first 16) | Word           | word-valid at 49922e9a                                       | word-valid at e08611b1                                       | strict at e08611b1                                                                                                               |
| ----- | --------- | ----------------------------- | ------- | ------------------------------- | ------------------ | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `s13` | 08:04:21Z | `s13-control-minimal`         | control | —                               | `bf084e7192d92d0d` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |
| `s13` | 08:04:14Z | `414-override-no-partname`    | #414    | `<Override>` without `PartName` | `241dec2cbbf10ab7` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s13` | 08:04:09Z | `414-override-empty-partname` | #414    | PartName `""`                   | `f2262394f44bc064` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s13` | 08:04:18Z | `414-override-slash-only`     | #414    | PartName `/`                    | `120aae863477e4b5` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`)                                                                     |
| `s13` | 08:04:21Z | `s13-control-minimal-end`     | control | —                               | `bf084e7192d92d0d` | clean-open     | valid                                                        | valid                                                        | valid                                                                                                                            |

<details><summary>Raw records, session 13</summary>

```jsonl
{"run": "s13", "name": "s13-control-minimal", "sha256": "bf084e7192d92d0ddc894e4e40ead93149f1fb6bddce181a6c3ce29b00613400", "observedAt": "2026-10-24T08:04:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s13", "name": "414-override-no-partname", "sha256": "241dec2cbbf10ab74de0610a175d9067f1798a3b66f64c6647091c96d71fac19", "observedAt": "2026-10-24T08:04:14.120Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__414-override-no-partname.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__414-override-no-partname.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s13", "name": "414-override-empty-partname", "sha256": "f2262394f44bc064d5ca243c9aed9f9f51d60680c3c07f08517ca165d137988a", "observedAt": "2026-10-24T08:04:09.830Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__414-override-empty-partname.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__414-override-empty-partname.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s13", "name": "414-override-slash-only", "sha256": "120aae863477e4b5ff9c282134d98f7475c9050a7b6a8d721658efa71a6c90d3", "observedAt": "2026-10-24T08:04:18.466Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__414-override-slash-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__414-override-slash-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s13", "name": "s13-control-minimal-end", "sha256": "bf084e7192d92d0ddc894e4e40ead93149f1fb6bddce181a6c3ce29b00613400", "observedAt": "2026-10-24T08:04:21+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 14: 08:57Z–09:01Z, validator columns at ed34e3bf

Markup Compatibility in `[Content_Types].xml` (#459) and bytes before the archive (#464). The Choice reads `Requires="x"` with `x` bound to `urn:x:unknown`, so a processor would take the Fallback. `/word/a%41b.xml` alone gets repair (session 11) and `/word/fallback.xml` alone opens clean (session 7). Each preflight shows `launched_by_us=True` and `open_documents=0`.

| Run    | Observed  | Specimen                           | Issue   | Shape                                                                          | SHA-256 (first 16) | Word           | word-valid at ed34e3bf                                       | strict at ed34e3bf                                                                                                               |
| ------ | --------- | ---------------------------------- | ------- | ------------------------------------------------------------------------------ | ------------------ | -------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `s14a` | 09:00:16Z | `s14a-control-minimal`             | control | —                                                                              | `cf3d7334a3e915bb` | clean-open     | valid                                                        | valid                                                                                                                            |
| `s14a` | 09:00:16Z | `459-mc-namespace-declared-only`   | #459    | `xmlns:mc` declared on `Types`, unused                                         | `c0d18ab449b669be` | clean-open     | valid                                                        | valid                                                                                                                            |
| `s14a` | 09:00:13Z | `459-mc-ignorable-only`            | #459    | `mc:Ignorable="x"` on `Types`                                                  | `08ae41c073579db4` | repair-warning | valid                                                        | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                     |
| `s14a` | 08:59:20Z | `459-mc-ignorable-ignored-element` | #459    | `mc:Ignorable="x"` and an `<x:Foo/>` child                                     | `292b5d5996b19a80` | repair-warning | valid                                                        | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                     |
| `s14a` | 08:57:36Z | `459-mc-choice-bad-fallback-good`  | #459    | `mc:AlternateContent`: Choice `/word/a%41b.xml`, Fallback `/word/fallback.xml` | `0a1001d5f0629b3a` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s14a` | 08:58:28Z | `459-mc-choice-good-fallback-bad`  | #459    | `mc:AlternateContent`: Choice `/word/fallback.xml`, Fallback `/word/a%41b.xml` | `5b5bad74b92b1239` | repair-warning | invalid (`ct-override-partname-invalid@[Content_Types].xml`) | invalid (`ct-override-partname-invalid@[Content_Types].xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s14a` | 09:00:16Z | `s14a-control-minimal-end`         | control | —                                                                              | `cf3d7334a3e915bb` | clean-open     | valid                                                        | valid                                                                                                                            |
| `s14b` | 09:01:11Z | `s14b-control-minimal`             | control | —                                                                              | `cf3d7334a3e915bb` | clean-open     | valid                                                        | valid                                                                                                                            |
| `s14b` | 09:01:09Z | `464-prefix-zip-docx`              | #464    | a 2-entry ZIP before the package                                               | `11d401efa68b3815` | repair-warning | invalid (`zip-bytes-after-eocd@-`)                           | invalid (`zip-bytes-after-eocd@-`)                                                                                               |
| `s14b` | 09:01:05Z | `464-prefix-junk-docx-relative`    | #464    | 4096 spaces before the package, offsets relative                               | `47401fd6ef941c04` | repair-warning | valid                                                        | valid                                                                                                                            |
| `s14b` | 09:01:00Z | `464-prefix-junk-docx-absolute`    | #464    | 4096 spaces before the package, offsets absolute                               | `8e4b03234f887784` | repair-warning | valid                                                        | valid                                                                                                                            |
| `s14b` | 09:01:11Z | `s14b-control-minimal-end`         | control | —                                                                              | `828d87c635821a14` | clean-open     | valid                                                        | valid                                                                                                                            |

The two `s14b` controls differ in 16 bytes, the DOS modification time of each entry in its local and central headers: JSZip stamps the build time, and the end control was built two seconds later.

<details><summary>Raw records, session 14</summary>

```jsonl
{"run": "s14a", "name": "s14a-control-minimal", "sha256": "cf3d7334a3e915bb920a7d95d4e355238b8cd0d5ff71fedc3fe713f2d10077d7", "observedAt": "2026-10-24T09:00:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s14a", "name": "459-mc-namespace-declared-only", "sha256": "c0d18ab449b669be416a623fc1e73666c96408661f5e9232a5c7f06867c5e3bb", "observedAt": "2026-10-24T09:00:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s14a", "name": "459-mc-ignorable-only", "sha256": "08ae41c073579db4c46ebadeb98cd16f21c349c6b93cf1bf40e261d61f8bc4cd", "observedAt": "2026-10-24T09:00:13.118Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__459-mc-ignorable-only.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00003__wfv__459-mc-ignorable-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__459-mc-ignorable-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14a", "name": "459-mc-ignorable-ignored-element", "sha256": "292b5d5996b19a80cc529a8967c72cbf3b843aae256cff050f1fab5644f7563b", "observedAt": "2026-10-24T08:59:20.697Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__459-mc-ignorable-ignored-element.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00002__wfv__459-mc-ignorable-ignored-element.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s14a", "name": "459-mc-choice-bad-fallback-good", "sha256": "0a1001d5f0629b3ad7ca713402e10a23b9436443452c075adc006ab35837c2d7", "observedAt": "2026-10-24T08:57:36.768Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__459-mc-choice-bad-fallback-good.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__459-mc-choice-bad-fallback-good.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14a", "name": "459-mc-choice-good-fallback-bad", "sha256": "5b5bad74b92b12397f44f140960852dc52d93b1d4215158230d25cd325e12b9c", "observedAt": "2026-10-24T08:58:28.648Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__459-mc-choice-good-fallback-bad.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__459-mc-choice-good-fallback-bad.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14a", "name": "s14a-control-minimal-end", "sha256": "cf3d7334a3e915bb920a7d95d4e355238b8cd0d5ff71fedc3fe713f2d10077d7", "observedAt": "2026-10-24T09:00:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s14b", "name": "s14b-control-minimal", "sha256": "cf3d7334a3e915bb920a7d95d4e355238b8cd0d5ff71fedc3fe713f2d10077d7", "observedAt": "2026-10-24T09:01:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s14b", "name": "464-prefix-zip-docx", "sha256": "11d401efa68b38151933f3b3ab6838c083038c458ac1a315ce2e3dbd42e0d5dc", "observedAt": "2026-10-24T09:01:09.200Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__464-prefix-zip-docx.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__464-prefix-zip-docx.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14b", "name": "464-prefix-junk-docx-relative", "sha256": "47401fd6ef941c0493b50c513e6cd49f36fe7a19def5f36b49fd3072b471cdb9", "observedAt": "2026-10-24T09:01:05.017Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__464-prefix-junk-docx-relative.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__464-prefix-junk-docx-relative.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14b", "name": "464-prefix-junk-docx-absolute", "sha256": "8e4b03234f8877847abb68015d1f89d04d53c9b1a4e0a008db018d802e4b3e7e", "observedAt": "2026-10-24T09:01:00.834Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__464-prefix-junk-docx-absolute.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__464-prefix-junk-docx-absolute.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s14b", "name": "s14b-control-minimal-end", "sha256": "828d87c635821a14fabb04b355991544f6a83cbe01dbd1661866db579eed5b36", "observedAt": "2026-10-24T09:01:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 15: 11:15Z–11:29Z, validator columns at 8252ce4f

Review AM's suspected findings F4–F9 on layers 78 and 79 (#437, #432), and the controls that separate their causes. Every malformed part is well formed up to a missing end tag of its root element, so its namespaces stay declared.

| Run    | Observed  | Specimen                                       | Issue      | Shape                                                                                                                  | SHA-256 (first 16) | Word           | word-valid at 8252ce4f                                      | strict at 8252ce4f                                                                                                          |
| ------ | --------- | ---------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `s15a` | 11:17:07Z | `s15a-control-minimal`                         | control    | —                                                                                                                      | `f787d3af2efc5e5c` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15a` | 11:15:47Z | `am-f4-docrels-unclosed`                       | #437 AM F4 | `word/_rels/document.xml.rels` missing its root end tag                                                                | `b2a488539185adba` | repair-warning | valid                                                       | invalid (`xml-syntax@word/_rels/document.xml.rels`, `rels-unreferenced@word/styles.xml`, `rels-id-parse@word/document.xml`) |
| `s15a` | 11:17:05Z | `am-f4-docrels-zero-byte`                      | #437 AM F4 | `word/_rels/document.xml.rels` zero bytes                                                                              | `6ebfc8452e1990a1` | repair-warning | valid                                                       | invalid (`xml-syntax@word/_rels/document.xml.rels`, `rels-unreferenced@word/styles.xml`, `rels-id-parse@word/document.xml`) |
| `s15a` | 11:17:07Z | `am-f7-comments-rangeonly-malformed`           | #437 AM F7 | comment range without `w:commentReference`; `word/comments.xml` malformed                                              | `38705692504e7647` | clean-open     | valid                                                       | invalid (`xml-syntax@word/comments.xml`)                                                                                    |
| `s15a` | 11:17:07Z | `am-f7-comments-rangeonly-wellformed-control`  | #437 AM F7 | comment range without `w:commentReference`; `word/comments.xml` well formed                                            | `c0d33add4942316f` | clean-open     | valid                                                       | invalid (`comment-thread-count-mismatch@word/document.xml`, `paraid-missing-element@word/comments.xml`)                     |
| `s15a` | 11:17:07Z | `s15a-control-minimal-end`                     | control    | —                                                                                                                      | `f787d3af2efc5e5c` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15b` | 11:18:48Z | `s15b-control-minimal`                         | control    | —                                                                                                                      | `7d2c71cd8e61c4b7` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15b` | 11:18:33Z | `am-f6-second-officedoc-malformed`             | #437 AM F6 | second `officeDocument` relationship to a malformed `alt/document.xml` (main type)                                     | `01636316e10ea478` | repair-warning | invalid (`xml-syntax@alt/document.xml`)                     | invalid (`xml-syntax@alt/document.xml`)                                                                                     |
| `s15b` | 11:18:37Z | `am-f6-second-officedoc-wellformed-control`    | #437 AM F6 | second `officeDocument` relationship to a well-formed `alt/document.xml` (main type)                                   | `8d260a4e265f6581` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15b` | 11:17:37Z | `am-f6-second-officedoc-generic-styles`        | #432 AM F6 | the same, plus `alt/styles.xml` typed by the generic `Default`                                                         | `9cbeeeb2699e370f` | repair-warning | invalid (`word-part-content-type-generic@alt/styles.xml`)   | invalid (`word-part-content-type-generic@alt/styles.xml`)                                                                   |
| `s15b` | 11:18:42Z | `am-f9-main-default-textxml`                   | #432 AM F9 | main part typed by `Default Extension="xml" ContentType="text/xml"`, no `Override`                                     | `ac96fc5dc55f694c` | repair-warning | valid                                                       | invalid (`ct-undeclared-part@word/document.xml`)                                                                            |
| `s15b` | 11:18:46Z | `am-f9-main-override-appxml`                   | #432 AM F9 | main part `Override` `application/xml`                                                                                 | `f71ec80920852339` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15b` | 11:18:48Z | `s15b-control-minimal-end`                     | control    | —                                                                                                                      | `7d2c71cd8e61c4b7` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15c` | 11:20:09Z | `s15c-control-minimal`                         | control    | —                                                                                                                      | `facd9aa52aabea33` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15c` | 11:19:19Z | `am-f8-header-outside-word-malformed`          | #437 AM F8 | malformed `hdr/header1.xml`, referenced by `w:headerReference`                                                         | `390c600f9edd77a3` | open-error     | valid                                                       | invalid (`xml-syntax@hdr/header1.xml`)                                                                                      |
| `s15c` | 11:20:09Z | `am-f8-header-outside-word-wellformed-control` | #437 AM F8 | well-formed `hdr/header1.xml`, referenced by `w:headerReference`                                                       | `b6114132a7eb39eb` | clean-open     | valid                                                       | invalid (`paraid-missing-element@hdr/header1.xml`)                                                                          |
| `s15c` | 11:19:15Z | `am-f8-endnotes-outside-word-malformed`        | #437 AM F8 | malformed `en/endnotes.xml`, used by `w:endnoteReference`                                                              | `f56d12f170b1da43` | repair-warning | valid                                                       | invalid (`xml-syntax@en/endnotes.xml`)                                                                                      |
| `s15c` | 11:20:09Z | `am-f5-styles-ms-namespace-malformed`          | #437 AM F5 | styles relationship typed `http://schemas.microsoft.com/office/2007/relationships/styles`; `word/styles.xml` malformed | `10d445a68baa05fa` | clean-open     | valid                                                       | invalid (`xml-syntax@word/styles.xml`)                                                                                      |
| `s15c` | 11:20:09Z | `am-f5-styles-package-rels-malformed`          | #437 AM F5 | a `styles` relationship in `_rels/.rels` to a malformed `word/styles2.xml`                                             | `8d468aa6ecda6b2f` | clean-open     | valid                                                       | invalid (`xml-syntax@word/styles2.xml`)                                                                                     |
| `s15c` | 11:20:09Z | `s15c-control-minimal-end`                     | control    | —                                                                                                                      | `facd9aa52aabea33` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15d` | 11:24:25Z | `s15d-control-minimal`                         | control    | —                                                                                                                      | `161a1ee6abb232b9` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15d` | 11:23:26Z | `am-f6-second-officedoc-no-override`           | #437 AM F6 | second `officeDocument` relationship to a well-formed `alt/document.xml`, no `Override`                                | `887a22c6cab119b5` | repair-warning | invalid (`word-part-content-type-generic@alt/document.xml`) | invalid (`ct-undeclared-part@alt/document.xml`)                                                                             |
| `s15d` | 11:24:25Z | `am-f6-orphan-main-typed-part`                 | #437 AM F6 | well-formed `alt/document.xml` with a main-type `Override`, no relationship                                            | `6c701f8e24034276` | clean-open     | valid                                                       | invalid (`rels-unreferenced@alt/document.xml`)                                                                              |
| `s15d` | 11:23:10Z | `am-f6-duplicate-officedoc-same-target`        | #437 AM F6 | second `officeDocument` relationship to `word/document.xml`                                                            | `f911d55857e031f6` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15d` | 11:24:23Z | `am-f8-theme-outside-word-malformed`           | #437 AM F8 | malformed `th/theme1.xml`, named by a document `theme` relationship                                                    | `6fbdf1e5b3dfb032` | repair-warning | valid                                                       | invalid (`xml-syntax@th/theme1.xml`)                                                                                        |
| `s15d` | 11:24:18Z | `am-f8-glossary-outside-word-malformed`        | #437 AM F8 | malformed `g/glossary.xml`, named by a document `glossaryDocument` relationship                                        | `1119f31f824b8598` | repair-warning | valid                                                       | invalid (`xml-syntax@g/glossary.xml`)                                                                                       |
| `s15d` | 11:24:25Z | `s15d-control-minimal-end`                     | control    | —                                                                                                                      | `161a1ee6abb232b9` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15e` | 11:29:16Z | `s15e-control-minimal`                         | control    | —                                                                                                                      | `edec7316af4b6eee` | clean-open     | valid                                                       | valid                                                                                                                       |
| `s15e` | 11:29:16Z | `am-f8-header-unused-malformed`                | #437 AM F8 | malformed `word/header1.xml`, related but not referenced                                                               | `1b218cd75afba5c5` | clean-open     | invalid (`xml-syntax@word/header1.xml`)                     | invalid (`xml-syntax@word/header1.xml`)                                                                                     |
| `s15e` | 11:29:16Z | `am-f8-endnotes-unused-malformed`              | #437 AM F8 | malformed `word/endnotes.xml`, related but not referenced                                                              | `19e8d098f9b8004b` | clean-open     | invalid (`xml-syntax@word/endnotes.xml`)                    | invalid (`xml-syntax@word/endnotes.xml`)                                                                                    |
| `s15e` | 11:29:14Z | `am-f9-styles-override-appxml`                 | #432 AM F9 | styles `Override` `application/xml`                                                                                    | `1631577166764ad8` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15e` | 11:29:10Z | `am-f9-styles-default-textxml`                 | #432 AM F9 | styles typed by `Default Extension="xml" ContentType="text/xml"`, no `Override`                                        | `27c199d32386ccba` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15e` | 11:29:06Z | `am-f9-main-override-textxml`                  | #432 AM F9 | main part `Override` `text/xml`                                                                                        | `dcfeae9604af9252` | repair-warning | valid                                                       | valid                                                                                                                       |
| `s15e` | 11:29:16Z | `s15e-control-minimal-end`                     | control    | —                                                                                                                      | `64394d37f2f367eb` | clean-open     | valid                                                       | valid                                                                                                                       |

The two `s15e` controls differ in 16 bytes, the DOS modification time of each entry in its local and central headers, as in `s14b`.

<details><summary>Raw records, session 15</summary>

```jsonl
{"run": "s15a", "name": "s15a-control-minimal", "sha256": "f787d3af2efc5e5c4d67c79e9339c1d93ee2d93025ef8870f49f237a296c3182", "observedAt": "2026-10-24T11:17:07+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15a", "name": "am-f4-docrels-unclosed", "sha256": "b2a488539185adba17c69770f9982aec76918d53aaaea0c8e36bf64afb6257a9", "observedAt": "2026-10-24T11:15:47.826Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__am-f4-docrels-unclosed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__am-f4-docrels-unclosed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15a", "name": "am-f4-docrels-zero-byte", "sha256": "6ebfc8452e1990a1e819b9e40e3be4491b816e2c8992c14e4791879ef10b191c", "observedAt": "2026-10-24T11:17:05.581Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00001__wfv__am-f4-docrels-zero-byte.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s15a", "name": "am-f7-comments-rangeonly-malformed", "sha256": "38705692504e7647d3136d7ddd0b29111d782ef03f1fd404d38b0e9e33dfa617", "observedAt": "2026-10-24T11:17:07+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15a", "name": "am-f7-comments-rangeonly-wellformed-control", "sha256": "c0d33add4942316f53a3431ba6fe4011091f21d80c02c463a2c2b5630d335fcc", "observedAt": "2026-10-24T11:17:07+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15a", "name": "s15a-control-minimal-end", "sha256": "f787d3af2efc5e5c4d67c79e9339c1d93ee2d93025ef8870f49f237a296c3182", "observedAt": "2026-10-24T11:17:07+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15b", "name": "s15b-control-minimal", "sha256": "7d2c71cd8e61c4b74de029eb375a84755ef719dbd71ccd0ad0d5b9f856c9372a", "observedAt": "2026-10-24T11:18:48+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15b", "name": "am-f6-second-officedoc-malformed", "sha256": "01636316e10ea478885d4d0d2d59874cb16274195f17b4990dde58c07fe393ef", "observedAt": "2026-10-24T11:18:33.604Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__am-f6-second-officedoc-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__am-f6-second-officedoc-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15b", "name": "am-f6-second-officedoc-wellformed-control", "sha256": "8d260a4e265f658108d171da6ae6ec0acc589cb57a652a0ec8f14683a69917d4", "observedAt": "2026-10-24T11:18:37.826Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__am-f6-second-officedoc-wellformed-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__am-f6-second-officedoc-wellformed-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15b", "name": "am-f6-second-officedoc-generic-styles", "sha256": "9cbeeeb2699e370fe2ad898b36c63c8b649721c6d2489b17e85496d3e3751ad1", "observedAt": "2026-10-24T11:17:37.642Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__am-f6-second-officedoc-generic-styles.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__am-f6-second-officedoc-generic-styles.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15b", "name": "am-f9-main-default-textxml", "sha256": "ac96fc5dc55f694c62d1c950d787928f205ea4aa9493062d9744471e1ae4ede6", "observedAt": "2026-10-24T11:18:42.025Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__am-f9-main-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__am-f9-main-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15b", "name": "am-f9-main-override-appxml", "sha256": "f71ec80920852339dac3f43198b10ba902e84861c0612c8d96ce1ac4d5717ddc", "observedAt": "2026-10-24T11:18:46.212Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__am-f9-main-override-appxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__am-f9-main-override-appxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15b", "name": "s15b-control-minimal-end", "sha256": "7d2c71cd8e61c4b74de029eb375a84755ef719dbd71ccd0ad0d5b9f856c9372a", "observedAt": "2026-10-24T11:18:48+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15c", "name": "s15c-control-minimal", "sha256": "facd9aa52aabea33d92b9f0d3a9af79a92f0cf74e3ac7c3736ab7d86a2537fc4", "observedAt": "2026-10-24T11:20:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15c", "name": "am-f8-header-outside-word-malformed", "sha256": "390c600f9edd77a3d8f5d7bf2e102d364a4e16cc2d6b16532118393df2ca2c6b", "observedAt": "2026-10-24T11:19:19.678Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00003__wfv__am-f8-header-outside-word-malformed.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15c", "name": "am-f8-header-outside-word-wellformed-control", "sha256": "b6114132a7eb39ebd0529806c63cb16888d7c41e12dc0926f847fc0640f02c94", "observedAt": "2026-10-24T11:20:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15c", "name": "am-f8-endnotes-outside-word-malformed", "sha256": "f56d12f170b1da43903ab5b7aa0acf64be4040b6eea5345bf571980c8b386f9b", "observedAt": "2026-10-24T11:19:15.116Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__am-f8-endnotes-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__am-f8-endnotes-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15c", "name": "am-f5-styles-ms-namespace-malformed", "sha256": "10d445a68baa05fa17f7e1a440eb01d8bf70c0ae93d0fef1823daa5be6d7418d", "observedAt": "2026-10-24T11:20:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15c", "name": "am-f5-styles-package-rels-malformed", "sha256": "8d468aa6ecda6b2f1c6cdd74718ba329d49fba952c9948964010daa4b42f602f", "observedAt": "2026-10-24T11:20:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15c", "name": "s15c-control-minimal-end", "sha256": "facd9aa52aabea33d92b9f0d3a9af79a92f0cf74e3ac7c3736ab7d86a2537fc4", "observedAt": "2026-10-24T11:20:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15d", "name": "s15d-control-minimal", "sha256": "161a1ee6abb232b904c8e2a1ed8318d10c4a1bf95a6772036dca0d0adfe1dfad", "observedAt": "2026-10-24T11:24:25+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15d", "name": "am-f6-second-officedoc-no-override", "sha256": "887a22c6cab119b506bc30cba972eb7f0b2dcbd7f8bbee87ff04922a3fb2677c", "observedAt": "2026-10-24T11:23:26.602Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__am-f6-second-officedoc-no-override.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00002__wfv__am-f6-second-officedoc-no-override.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s15d", "name": "am-f6-orphan-main-typed-part", "sha256": "6c701f8e24034276b088f515cf0efd37aa30da629932b8de495b1786fec70ae5", "observedAt": "2026-10-24T11:24:25+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15d", "name": "am-f6-duplicate-officedoc-same-target", "sha256": "f911d55857e031f6cca67158fe0755730ac2feac99806e32e664e796aeda7fee", "observedAt": "2026-10-24T11:23:10.911Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__am-f6-duplicate-officedoc-same-target.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__am-f6-duplicate-officedoc-same-target.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15d", "name": "am-f8-theme-outside-word-malformed", "sha256": "6fbdf1e5b3dfb032d4b12d3ca769302641e074681b26ecaf83f27dd5b04ec923", "observedAt": "2026-10-24T11:24:23.394Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__am-f8-theme-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__am-f8-theme-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15d", "name": "am-f8-glossary-outside-word-malformed", "sha256": "1119f31f824b8598c3f63c88755648e0541557488b11e5275d6828c10d689a4f", "observedAt": "2026-10-24T11:24:18.699Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__am-f8-glossary-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__am-f8-glossary-outside-word-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15d", "name": "s15d-control-minimal-end", "sha256": "161a1ee6abb232b904c8e2a1ed8318d10c4a1bf95a6772036dca0d0adfe1dfad", "observedAt": "2026-10-24T11:24:25+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15e", "name": "s15e-control-minimal", "sha256": "edec7316af4b6eeea762ca05f6eae584c600f95aff54b891bf4248e912fb8337", "observedAt": "2026-10-24T11:29:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15e", "name": "am-f8-header-unused-malformed", "sha256": "1b218cd75afba5c5deb5da365cdc4e542e554cf00f313f64575fce99217d5236", "observedAt": "2026-10-24T11:29:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15e", "name": "am-f8-endnotes-unused-malformed", "sha256": "19e8d098f9b8004b50c41598d37b6d1931dbd7d8448136044b3612d595205773", "observedAt": "2026-10-24T11:29:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s15e", "name": "am-f9-styles-override-appxml", "sha256": "1631577166764ad802aa5d3d362da110b9c689e5a3046745ef5ae6bb9ddb2c26", "observedAt": "2026-10-24T11:29:14.823Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__am-f9-styles-override-appxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__am-f9-styles-override-appxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15e", "name": "am-f9-styles-default-textxml", "sha256": "27c199d32386ccba6170441b61921a03e346ec0d5d8fee3032554ac096c8a120", "observedAt": "2026-10-24T11:29:10.573Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__am-f9-styles-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__am-f9-styles-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15e", "name": "am-f9-main-override-textxml", "sha256": "dcfeae9604af9252b0c3adf5de67b31d1dcb703ac18e6800b123c337f262ff10", "observedAt": "2026-10-24T11:29:06.340Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__am-f9-main-override-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__am-f9-main-override-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s15e", "name": "s15e-control-minimal-end", "sha256": "64394d37f2f367eb60d414d225d2c27705dead8849757f8b5535992a3b2eccb7", "observedAt": "2026-10-24T11:29:16+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 16: 12:49Z–12:50Z, validator columns at 98902c85

Review AR's suspected items on layers 89–92 (references from other stories, #516; MIME parameters on content types, #517) and the shapes of its finding F1 (#535). Every malformed part is well formed up to a missing end tag of its root element, so its namespaces stay declared.

| Run    | Observed  | Specimen                                        | Issue             | Shape                                                                                                     | SHA-256 (first 16) | Word           | word-valid at 98902c85                                           | strict at 98902c85                                                                                                |
| ------ | --------- | ----------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `s16a` | 12:49:19Z | `s16a-control-minimal`                          | control           | —                                                                                                         | `fe2a0002a6778723` | clean-open     | valid                                                            | valid                                                                                                             |
| `s16a` | 12:49:19Z | `ar-endnote-ref-in-footnote-malformed`          | #516 AR suspected | `w:endnoteReference` only inside a footnote (main references the footnote); `word/endnotes.xml` malformed | `40c5524a7ee87ebe` | clean-open     | valid                                                            | invalid (`xml-syntax@word/endnotes.xml`, `paraid-missing-element@word/footnotes.xml`)                             |
| `s16a` | 12:49:19Z | `ar-endnote-ref-in-footnote-wellformed-control` | #516 AR suspected | `w:endnoteReference` only inside a footnote; `word/endnotes.xml` well formed                              | `b65fb7be04526dea` | clean-open     | valid                                                            | invalid (`paraid-missing-element@word/endnotes.xml`, `paraid-missing-element@word/footnotes.xml`)                 |
| `s16a` | 12:49:17Z | `ar-header-ref-in-glossary-malformed`           | #516 AR suspected | `w:headerReference` only in a glossary `w:docPartBody` `w:sectPr`; `word/glossary/header9.xml` malformed  | `a9d3c660c1ba09c1` | repair-warning | valid                                                            | invalid (`xml-syntax@word/glossary/header9.xml`, `paraid-missing-element@word/glossary/document.xml`)             |
| `s16a` | 12:49:19Z | `ar-header-ref-in-glossary-wellformed-control`  | #516 AR suspected | `w:headerReference` only in a glossary `w:docPartBody` `w:sectPr`; header well formed                     | `acbbb90b2033c15f` | clean-open     | valid                                                            | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`) |
| `s16a` | 12:49:19Z | `s16a-control-minimal-end`                      | control           | —                                                                                                         | `c83e4293642a6f03` | clean-open     | valid                                                            | valid                                                                                                             |
| `s16b` | 12:50:11Z | `s16b-control-minimal`                          | control           | —                                                                                                         | `e33e187d31bded6b` | clean-open     | valid                                                            | valid                                                                                                             |
| `s16b` | 12:50:06Z | `ar-styles-override-appxml-charset`             | #517 AR suspected | styles `Override` `application/xml; charset=utf-8`                                                        | `e7112063b13c4c10` | repair-warning | valid                                                            | valid                                                                                                             |
| `s16b` | 12:50:10Z | `ar-styles-override-proper-charset`             | #517 AR suspected | styles `Override` with the styles type plus `; charset=utf-8`                                             | `c4bfb8e9df16e499` | repair-warning | valid                                                            | valid                                                                                                             |
| `s16b` | 12:50:01Z | `ar-main-override-proper-charset`               | #517 AR suspected | main part `Override` with the main type plus `; charset=utf-8`                                            | `c04a9070f21390ad` | repair-warning | valid                                                            | valid                                                                                                             |
| `s16b` | 12:49:53Z | `ar-f1-main-bin-default-textxml`                | #535 AR F1        | main part stored as `word/document.bin`, typed by `Default Extension="bin" ContentType="text/xml"`        | `9c5230c7d9bf48c7` | repair-warning | invalid (`word-part-content-type-generic@word/document.bin`)     | valid                                                                                                             |
| `s16b` | 12:50:11Z | `ar-f1-main-bin-default-maintype-control`       | #535 AR F1        | main part stored as `word/document.bin`, typed by a `bin` `Default` with the main type                    | `3e7bb45ce09a8fda` | clean-open     | valid                                                            | valid                                                                                                             |
| `s16b` | 12:49:57Z | `ar-f1-main-docprops-default-textxml`           | #535 AR F1        | main part stored as `docProps/document.xml`, typed by `Default Extension="xml" ContentType="text/xml"`    | `631e174646bfb7cf` | repair-warning | invalid (`word-part-content-type-generic@docProps/document.xml`) | valid                                                                                                             |
| `s16b` | 12:50:11Z | `s16b-control-minimal-end`                      | control           | —                                                                                                         | `e33e187d31bded6b` | clean-open     | valid                                                            | valid                                                                                                             |

The two `s16a` controls differ in 16 bytes, the DOS modification time of each entry in its local and central headers, as in `s14b`. The two `s16b` controls are byte-identical.

<details><summary>Raw records, session 16</summary>

```jsonl
{"run": "s16a", "name": "s16a-control-minimal", "sha256": "fe2a0002a67787236745e534894f3dea1fe561b3b92793f5857e2fd7b358dbfc", "observedAt": "2026-10-24T12:49:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16a", "name": "ar-endnote-ref-in-footnote-malformed", "sha256": "40c5524a7ee87ebebe2be937cc47d30313684e815a665e42b4a21cdf53b7f4df", "observedAt": "2026-10-24T12:49:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16a", "name": "ar-endnote-ref-in-footnote-wellformed-control", "sha256": "b65fb7be04526dea4f955e2d920071dfc38c5bf67459cc1cadf7f23734ca1839", "observedAt": "2026-10-24T12:49:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16a", "name": "ar-header-ref-in-glossary-malformed", "sha256": "a9d3c660c1ba09c15509c1bdbc9c4dd7934d3289f097c0c1fd24c372cf2bccd6", "observedAt": "2026-10-24T12:49:17.778Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__ar-header-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__ar-header-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16a", "name": "ar-header-ref-in-glossary-wellformed-control", "sha256": "acbbb90b2033c15f8c22402e3d9b3d44fff8621132779b39acb327d89468cd78", "observedAt": "2026-10-24T12:49:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16a", "name": "s16a-control-minimal-end", "sha256": "c83e4293642a6f03f36ae3e623d5ebc046d6fd6bc2ca4305e2a893f85584d194", "observedAt": "2026-10-24T12:49:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16b", "name": "s16b-control-minimal", "sha256": "e33e187d31bded6b72245a13e856ee091230f57931d3c31dd1896d296b378a8e", "observedAt": "2026-10-24T12:50:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16b", "name": "ar-styles-override-appxml-charset", "sha256": "e7112063b13c4c109131cae35a90d28aaf9bfb27827763dc6df9db72e3549c7d", "observedAt": "2026-10-24T12:50:06.113Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__ar-styles-override-appxml-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__ar-styles-override-appxml-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16b", "name": "ar-styles-override-proper-charset", "sha256": "c4bfb8e9df16e499938ff30e8e0b6cdea6f1e56a9c83879041830ee46ca81867", "observedAt": "2026-10-24T12:50:10.295Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__ar-styles-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__ar-styles-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16b", "name": "ar-main-override-proper-charset", "sha256": "c04a9070f21390add1373bd11b865fbfc20c0a80b8d306e069f368c425af19d8", "observedAt": "2026-10-24T12:50:01.913Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__ar-main-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__ar-main-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16b", "name": "ar-f1-main-bin-default-textxml", "sha256": "9c5230c7d9bf48c7c66a3aeb110e14fd75c0c2120d9c3b25da9c6f50dad37c37", "observedAt": "2026-10-24T12:49:53.212Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__ar-f1-main-bin-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__ar-f1-main-bin-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16b", "name": "ar-f1-main-bin-default-maintype-control", "sha256": "3e7bb45ce09a8fdae69086b2593af8bcb1df4c030e21669efa7f01ed576c7fc8", "observedAt": "2026-10-24T12:50:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s16b", "name": "ar-f1-main-docprops-default-textxml", "sha256": "631e174646bfb7cfbd1208874c84a0f08ea150417bef2ce115587376a9a477d4", "observedAt": "2026-10-24T12:49:57.746Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__ar-f1-main-docprops-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__ar-f1-main-docprops-default-textxml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s16b", "name": "s16b-control-minimal-end", "sha256": "e33e187d31bded6b72245a13e856ee091230f57931d3c31dd1896d296b378a8e", "observedAt": "2026-10-24T12:50:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 17: 13:04Z–13:11Z, validator columns at 3ebe3e7f

The open questions of #539 and #540: what Word reads through the glossary document, and which content-type spellings it refuses. Every malformed part is well formed up to a missing end tag of its root element, so its namespaces stay declared.

| Run    | Observed  | Specimen                                        | Issue              | Shape                                                                                                                        | SHA-256 (first 16) | Word           | word-valid at 3ebe3e7f                                                 | strict at 3ebe3e7f                                                                                                                                                                                                                                               |
| ------ | --------- | ----------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s17a` | 13:06:35Z | `s17a-control-minimal`                          | control            | —                                                                                                                            | `3d744ffea7631b24` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17a` | 13:06:00Z | `glossary-rels-unclosed`                        | #539 open question | the glossary's `word/glossary/_rels/document.xml.rels` missing its root end tag; the glossary references the header it names | `fa3c7836c343eee0` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/_rels/document.xml.rels`, `rels-unreferenced@word/glossary/header9.xml`, `rels-id-parse@word/glossary/document.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`) |
| `s17a` | 13:06:34Z | `glossary-rels-zero-byte`                       | #539 open question | the glossary's relationships part zero bytes; the glossary references a header                                               | `7db393414867ddf5` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/_rels/document.xml.rels`, `rels-unreferenced@word/glossary/header9.xml`, `rels-id-parse@word/glossary/document.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`) |
| `s17a` | 13:05:00Z | `footer-ref-in-glossary-malformed`              | #539 open question | `w:footerReference` only in a glossary `w:docPartBody` `w:sectPr`; `word/glossary/footer9.xml` malformed                     | `1c44bf9bb6baa870` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/footer9.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                            |
| `s17a` | 13:06:35Z | `footer-ref-in-glossary-wellformed-control`     | #539 open question | `w:footerReference` only in a glossary `w:docPartBody` `w:sectPr`; footer well formed                                        | `f095b53a59689923` | clean-open     | valid                                                                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)                                                                                                                                                |
| `s17a` | 13:05:13Z | `footnotes-ref-in-glossary-malformed`           | #539 open question | `w:footnoteReference` only in a glossary `w:docPartBody`; the glossary's `word/glossary/footnotes.xml` malformed             | `79bcfc7b195f4b80` | repair-warning | invalid (`word-footnote-reference-missing@word/glossary/document.xml`) | invalid (`xml-syntax@word/glossary/footnotes.xml`, `paraid-missing-element@word/glossary/document.xml`, `word-footnote-reference-missing@word/glossary/document.xml`)                                                                                            |
| `s17a` | 13:06:35Z | `header-related-from-glossary-unused-malformed` | #539 open question | malformed `word/glossary/header9.xml` related from the glossary, not referenced                                              | `b2e702efa3f9a7bc` | clean-open     | valid                                                                  | invalid (`xml-syntax@word/glossary/header9.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                            |
| `s17a` | 13:06:35Z | `s17a-control-minimal-end`                      | control            | —                                                                                                                            | `3d744ffea7631b24` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:08:34Z | `s17b-control-minimal`                          | control            | —                                                                                                                            | `3d744ffea7631b24` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:08:34Z | `settings-override-proper-control`              | #540 open question | `word/settings.xml` related, settings `Override` with the settings type                                                      | `e1e4243c7cd61e87` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:08:18Z | `settings-override-proper-charset`              | #540 open question | settings `Override` with the settings type plus `; charset=utf-8`                                                            | `2232255705b574aa` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:07:05Z | `fonttable-override-proper-charset`             | #540 open question | fontTable `Override` with the fontTable type plus `; charset=utf-8`                                                          | `9f5b99e33a9062b5` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:08:34Z | `websettings-override-proper-charset`           | #540 open question | webSettings `Override` with the webSettings type plus `; charset=utf-8`                                                      | `033486301174fa72` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17b` | 13:07:59Z | `header-override-proper-charset`                | #540 open question | referenced `word/header9.xml`, header `Override` with the header type plus `; charset=utf-8`                                 | `c9bb02ffde2142fa` | repair-warning | valid                                                                  | invalid (`paraid-missing-element@word/header9.xml`)                                                                                                                                                                                                              |
| `s17b` | 13:08:34Z | `header-override-proper-control`                | #540 open question | referenced `word/header9.xml`, header `Override` with the header type                                                        | `5a939418a8938c65` | clean-open     | valid                                                                  | invalid (`paraid-missing-element@word/header9.xml`)                                                                                                                                                                                                              |
| `s17b` | 13:08:34Z | `s17b-control-minimal-end`                      | control            | —                                                                                                                            | `3d744ffea7631b24` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:50Z | `s17c-control-minimal`                          | control            | —                                                                                                                            | `c7db8b9b275fc376` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:50Z | `main-override-uppercase-type`                  | #540 open question | main part `Override` with the main type in upper case                                                                        | `401cc0ef2f23166c` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:50Z | `styles-override-uppercase-type`                | #540 open question | styles `Override` with the styles type in upper case                                                                         | `2ac7eab516f0ac20` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:49Z | `styles-override-trailing-space`                | #540 open question | styles `Override` with the styles type plus a trailing space                                                                 | `0c32ea59551ca6b5` | repair-warning | valid                                                                  | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                                                                                                                                                     |
| `s17c` | 13:09:36Z | `main-override-proper-charset-nospace`          | #540 open question | main part `Override` with the main type plus `;charset=utf-8`                                                                | `71f0b5a95d80c4e4` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:40Z | `main-override-proper-other-param`              | #540 open question | main part `Override` with the main type plus `; foo=bar`                                                                     | `1cfec569c7dfa6dc` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:45Z | `styles-default-appxml-charset`                 | #540 open question | styles typed by `Default Extension="xml" ContentType="application/xml; charset=utf-8"`, no `Override`                        | `f832b0eec3827417` | repair-warning | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17c` | 13:09:50Z | `s17c-control-minimal-end`                      | control            | —                                                                                                                            | `c7db8b9b275fc376` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17d` | 13:10:56Z | `s17d-control-minimal`                          | control            | —                                                                                                                            | `e4936af1dd6dadae` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |
| `s17d` | 13:10:56Z | `footnotes-ref-in-glossary-wellformed-control`  | #539 open question | `w:footnoteReference` only in a glossary `w:docPartBody`; the glossary's footnotes well formed                               | `b62ef37b078431dc` | clean-open     | valid                                                                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footnotes.xml`)                                                                                                                                              |
| `s17d` | 13:10:49Z | `endnotes-ref-in-glossary-malformed`            | #539 open question | `w:endnoteReference` only in a glossary `w:docPartBody`; the glossary's `word/glossary/endnotes.xml` malformed               | `cf76e90b161a8649` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/endnotes.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                           |
| `s17d` | 13:10:56Z | `endnotes-ref-in-glossary-wellformed-control`   | #539 open question | `w:endnoteReference` only in a glossary `w:docPartBody`; the glossary's endnotes well formed                                 | `ab743f216b25f4b8` | clean-open     | valid                                                                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/endnotes.xml`)                                                                                                                                               |
| `s17d` | 13:10:45Z | `comments-ref-in-glossary-malformed`            | #539 open question | `w:commentReference` only in a glossary `w:docPartBody`; the glossary's `word/glossary/comments.xml` malformed               | `8453cea9c0c2a423` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/comments.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                           |
| `s17d` | 13:10:56Z | `comments-ref-in-glossary-wellformed-control`   | #539 open question | `w:commentReference` only in a glossary `w:docPartBody`; the glossary's comments well formed                                 | `56a8c1ff5bffedb8` | clean-open     | valid                                                                  | invalid (`comment-thread-count-mismatch@word/glossary/document.xml`, `paraid-missing-element@word/glossary/comments.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                   |
| `s17d` | 13:10:54Z | `glossary-rels-unclosed-unreferenced`           | #539 open question | the glossary's relationships part missing its root end tag; the glossary references nothing                                  | `19cea53b8695bc8b` | repair-warning | valid                                                                  | invalid (`xml-syntax@word/glossary/_rels/document.xml.rels`, `rels-unreferenced@word/glossary/header9.xml`, `rels-id-parse@word/glossary/document.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`) |
| `s17d` | 13:10:56Z | `s17d-control-minimal-end`                      | control            | —                                                                                                                            | `e4936af1dd6dadae` | clean-open     | valid                                                                  | valid                                                                                                                                                                                                                                                            |

Within each chunk, the two controls are byte-identical. The `s17a` and `s17b` controls are identical too.

<details><summary>Raw records, session 17</summary>

```jsonl
{"run": "s17a", "name": "s17a-control-minimal", "sha256": "3d744ffea7631b2462a06980bce82eb185da0cedbda783c8fce5c696486c0765", "observedAt": "2026-10-24T13:06:35+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17a", "name": "glossary-rels-unclosed", "sha256": "fa3c7836c343eee02dba9545fd8a19032bcab537962ab0b0ecf622758a5e90f3", "observedAt": "2026-10-24T13:06:00.837Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__glossary-rels-unclosed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__glossary-rels-unclosed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17a", "name": "glossary-rels-zero-byte", "sha256": "7db393414867ddf53194ef15d597633a00a5729c0f9a154829fa521bdf5eb743", "observedAt": "2026-10-24T13:06:34.334Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__glossary-rels-zero-byte.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-rels-zero-byte.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-rels-zero-byte.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17a", "name": "footer-ref-in-glossary-malformed", "sha256": "1c44bf9bb6baa87093d2a3f9934c8e95aba2bf29b303d8c23ad43112c11644a8", "observedAt": "2026-10-24T13:05:00.333Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__footer-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__footer-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17a", "name": "footer-ref-in-glossary-wellformed-control", "sha256": "f095b53a596899234b4478ca80de2a46bc88ead446bb6ff0612e704d9e1a4967", "observedAt": "2026-10-24T13:06:35+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17a", "name": "footnotes-ref-in-glossary-malformed", "sha256": "79bcfc7b195f4b8084e7d2b1d602bcd4646e475ed1e00318f391a5e9877f76b7", "observedAt": "2026-10-24T13:05:13.791Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00002__wfv__footnotes-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17a", "name": "header-related-from-glossary-unused-malformed", "sha256": "b2e702efa3f9a7bc77f55db48e0746631d34284edea7e7df44d0e9b95e9dc4fb", "observedAt": "2026-10-24T13:06:35+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17a", "name": "s17a-control-minimal-end", "sha256": "3d744ffea7631b2462a06980bce82eb185da0cedbda783c8fce5c696486c0765", "observedAt": "2026-10-24T13:06:35+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17b", "name": "s17b-control-minimal", "sha256": "3d744ffea7631b2462a06980bce82eb185da0cedbda783c8fce5c696486c0765", "observedAt": "2026-10-24T13:08:34+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17b", "name": "settings-override-proper-control", "sha256": "e1e4243c7cd61e87b9a9c8c195bc00d8f763047cf90e26e4867b3781a24a27dd", "observedAt": "2026-10-24T13:08:34+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17b", "name": "settings-override-proper-charset", "sha256": "2232255705b574aa4d77c96485cfdc73d64569cff0e97213c96576d7b3e276e2", "observedAt": "2026-10-24T13:08:18.275Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00005__wfv__settings-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17b", "name": "fonttable-override-proper-charset", "sha256": "9f5b99e33a9062b586614a9d05e2f44a0a463c48b88eaa744a94a4663c21f399", "observedAt": "2026-10-24T13:07:05.098Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__fonttable-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__fonttable-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17b", "name": "websettings-override-proper-charset", "sha256": "033486301174fa72539327abb3926c27b272e1929f026363d18756e63dd34abb", "observedAt": "2026-10-24T13:08:34.086Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__websettings-override-proper-charset.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00007__wfv__websettings-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17b", "name": "header-override-proper-charset", "sha256": "c9bb02ffde2142faec82c0f878066929ce55a420ec4bf3e106739d7ae1caf2d5", "observedAt": "2026-10-24T13:07:59.844Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__header-override-proper-charset.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00001__wfv__header-override-proper-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17b", "name": "header-override-proper-control", "sha256": "5a939418a8938c654644abd2fc3e2be349f33c639a25996d717699e56d60525e", "observedAt": "2026-10-24T13:08:34+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17b", "name": "s17b-control-minimal-end", "sha256": "3d744ffea7631b2462a06980bce82eb185da0cedbda783c8fce5c696486c0765", "observedAt": "2026-10-24T13:08:34+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17c", "name": "s17c-control-minimal", "sha256": "c7db8b9b275fc3765a8f0de40c2b85cf444bee095f103f868153ad8e4c80dd39", "observedAt": "2026-10-24T13:09:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17c", "name": "main-override-uppercase-type", "sha256": "401cc0ef2f23166ccb0ba34027ea6df79d56ccccbbfea0f63b8882bcca9b2274", "observedAt": "2026-10-24T13:09:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17c", "name": "styles-override-uppercase-type", "sha256": "2ac7eab516f0ac20b7d4247e9f0e887dd6f39a946277fc962ee0e804549e5266", "observedAt": "2026-10-24T13:09:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17c", "name": "styles-override-trailing-space", "sha256": "0c32ea59551ca6b508207f254fcb327dadbc29df694c03ce7ec6d69980682346", "observedAt": "2026-10-24T13:09:49.335Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__styles-override-trailing-space.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__styles-override-trailing-space.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17c", "name": "main-override-proper-charset-nospace", "sha256": "71f0b5a95d80c4e4ad3408a1549cc65eefde5a974dd2a1785e4810cf9abec2a7", "observedAt": "2026-10-24T13:09:36.809Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00000__wfv__main-override-proper-charset-nospace.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s17c", "name": "main-override-proper-other-param", "sha256": "1cfec569c7dfa6dc31168916bae3c1b3f77fa6500c5d8c867a6a3e8ae1b92731", "observedAt": "2026-10-24T13:09:40.736Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__main-override-proper-other-param.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__main-override-proper-other-param.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17c", "name": "styles-default-appxml-charset", "sha256": "f832b0eec3827417b21b6f66ff96ba63eba76129132a9c73a85c0f3ae400cb51", "observedAt": "2026-10-24T13:09:45.086Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__styles-default-appxml-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__styles-default-appxml-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17c", "name": "s17c-control-minimal-end", "sha256": "c7db8b9b275fc3765a8f0de40c2b85cf444bee095f103f868153ad8e4c80dd39", "observedAt": "2026-10-24T13:09:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17d", "name": "s17d-control-minimal", "sha256": "e4936af1dd6dadae0641797d95e3488aba8a5a1666ba1f9750c03f087cf45d03", "observedAt": "2026-10-24T13:10:56+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17d", "name": "footnotes-ref-in-glossary-wellformed-control", "sha256": "b62ef37b078431dc6e86a9b1cc99f84cf98f30631ac7bcb239c193438fb2a6f9", "observedAt": "2026-10-24T13:10:56+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17d", "name": "endnotes-ref-in-glossary-malformed", "sha256": "cf76e90b161a86492e4a0ca1d5405c871fedb6e34c1d6e0a419da0e4ee92cae9", "observedAt": "2026-10-24T13:10:49.951Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__endnotes-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__endnotes-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17d", "name": "endnotes-ref-in-glossary-wellformed-control", "sha256": "ab743f216b25f4b83cbc85044bfb095e2f7cbcd0fb1b694cb2e99756aefe235d", "observedAt": "2026-10-24T13:10:56+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17d", "name": "comments-ref-in-glossary-malformed", "sha256": "8453cea9c0c2a423f978a4cc0d1f42bf947eab5a59ba188c02243833cab2b995", "observedAt": "2026-10-24T13:10:45.574Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__comments-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__comments-ref-in-glossary-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17d", "name": "comments-ref-in-glossary-wellformed-control", "sha256": "56a8c1ff5bffedb829953e67cb462ca6dda0e2bcaa859c28ab8c29b636be0eea", "observedAt": "2026-10-24T13:10:56+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s17d", "name": "glossary-rels-unclosed-unreferenced", "sha256": "19cea53b8695bc8b5c688397665f420f025aa2ffc535cc3839de6676a8211a95", "observedAt": "2026-10-24T13:10:54.350Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__glossary-rels-unclosed-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__glossary-rels-unclosed-unreferenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s17d", "name": "s17d-control-minimal-end", "sha256": "e4936af1dd6dadae0641797d95e3488aba8a5a1666ba1f9750c03f087cf45d03", "observedAt": "2026-10-24T13:10:56+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 18: 13:18Z–13:19Z, validator columns at ab1fba79

Review AS's suspected item S3 (#441): stored names that differ only by Unicode normalization. Each extra part is a well-formed, unreferenced `<x/>` typed by the generic `xml` `Default`.

| Run    | Observed  | Specimen                   | Issue          | Shape                                                        | SHA-256 (first 16) | Word           | word-valid at ab1fba79                                                                                                           | strict at ab1fba79                                                                                                                              |
| ------ | --------- | -------------------------- | -------------- | ------------------------------------------------------------ | ------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `s18a` | 13:19:31Z | `s18a-control-minimal`     | control        | —                                                            | `eed77cd1accfa652` | clean-open     | valid                                                                                                                            | valid                                                                                                                                           |
| `s18a` | 13:19:10Z | `nfc-name-alone`           | S3 calibration | unreferenced well-formed `word/café.xml`, NFC (`é` = U+00E9) | `86909f8f805fd5ff` | repair-warning | invalid (`opc-part-name-word-refused@word/café.xml`)                                                                             | invalid (`rels-unreferenced@word/café.xml`, `xsd-summary@word/café.xml`, `xsd-error@word/café.xml`, `opc-part-name-word-refused@word/café.xml`) |
| `s18a` | 13:19:29Z | `nfd-name-alone`           | S3 calibration | unreferenced well-formed `word/café.xml`, NFD (`e` + U+0301) | `81fdf03d2e61ff8e` | repair-warning | invalid (`opc-part-name-word-refused@word/café.xml`)                                                                             | invalid (`rels-unreferenced@word/café.xml`, `xsd-summary@word/café.xml`, `xsd-error@word/café.xml`, `opc-part-name-word-refused@word/café.xml`) |
| `s18a` | 13:19:19Z | `nfc-nfd-part-pair`        | #441 S3        | both: `word/café.xml` NFC and NFD                            | `cabb04e95b352d73` | repair-warning | invalid (`opc-part-name-word-refused@word/café.xml`, `opc-part-name-word-refused@word/café.xml`, `package-extract-failed@-`)     | invalid (`opc-part-name-word-refused@word/café.xml`, `opc-part-name-word-refused@word/café.xml`, `package-extract-failed@-`)                    |
| `s18a` | 13:19:14Z | `nfc-nfd-folder-pair`      | #441 S3        | `word/café/a.xml` NFC and `word/café/b.xml` NFD              | `4ae45c123ba0c921` | repair-warning | invalid (`opc-part-name-word-refused@word/café/b.xml`, `opc-part-name-word-refused@word/café/a.xml`, `package-extract-failed@-`) | invalid (`opc-part-name-word-refused@word/café/b.xml`, `opc-part-name-word-refused@word/café/a.xml`, `package-extract-failed@-`)                |
| `s18a` | 13:19:06Z | `case-part-pair-control`   | #351 control   | `word/extra.xml` and `word/EXTRA.xml`                        | `afc124cc2608bb36` | repair-warning | invalid (`opc-equivalent-part-names@word/extra.xml`, `package-extract-failed@-`)                                                 | invalid (`opc-equivalent-part-names@word/extra.xml`, `package-extract-failed@-`)                                                                |
| `s18a` | 13:19:31Z | `s18a-control-minimal-end` | control        | —                                                            | `eed77cd1accfa652` | clean-open     | valid                                                                                                                            | valid                                                                                                                                           |

The two controls are byte-identical.

<details><summary>Raw records, session 18</summary>

```jsonl
{"run": "s18a", "name": "s18a-control-minimal", "sha256": "eed77cd1accfa6524774a1516873f7f64c6162170c35d62c24ff306c956f1ec7", "observedAt": "2026-10-24T13:19:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s18a", "name": "nfc-name-alone", "sha256": "86909f8f805fd5ff520928d870cd523fa1bd89a5476802c15afa34c1f41f6192", "observedAt": "2026-10-24T13:19:10.783Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__nfc-name-alone.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__nfc-name-alone.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s18a", "name": "nfd-name-alone", "sha256": "81fdf03d2e61ff8e6186a60e7089a212ac190649f16350dc9a62dcfa91530df6", "observedAt": "2026-10-24T13:19:29.066Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__nfd-name-alone.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__nfd-name-alone.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s18a", "name": "nfc-nfd-part-pair", "sha256": "cabb04e95b352d73889b4de7bed9e30325f6bca1de76ecc7c28d806679b7ba06", "observedAt": "2026-10-24T13:19:19.220Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__nfc-nfd-part-pair.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__nfc-nfd-part-pair.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s18a", "name": "nfc-nfd-folder-pair", "sha256": "4ae45c123ba0c92121c310bfea93e886f747978ded41aa383ba12af164225907", "observedAt": "2026-10-24T13:19:14.990Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__nfc-nfd-folder-pair.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__nfc-nfd-folder-pair.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s18a", "name": "case-part-pair-control", "sha256": "afc124cc2608bb3652999ff00a7076e7bb8e97401fc18bd9df7948234fe8fca1", "observedAt": "2026-10-24T13:19:06.565Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__case-part-pair-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__case-part-pair-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s18a", "name": "s18a-control-minimal-end", "sha256": "eed77cd1accfa6524774a1516873f7f64c6162170c35d62c24ff306c956f1ec7", "observedAt": "2026-10-24T13:19:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 19: 13:56Z–13:58Z, validator columns at 4c86cbfe

The glossary's eagerly parsed parts (#562). Each glossary specimen is the minimal package plus `word/glossary/document.xml`, reached through a main-document `glossaryDocument` relationship and referencing no story, whose own relationships part relates one part of the named type under `word/glossary/`, with that type's Word `Override`. "Unclosed" drops the part's root end tag.

| Run    | Observed  | Specimen                                  | Issue      | Shape                                                                                                                           | SHA-256 (first 16) | Word           | word-valid at 4c86cbfe | strict at 4c86cbfe                                                                                        |
| ------ | --------- | ----------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------- | --------------------------------------------------------------------------------------------------------- |
| `s19a` | 13:58:08Z | `s19a-control-minimal`                    | control    | —                                                                                                                               | `771b090b1d7159c5` | clean-open     | valid                  | valid                                                                                                     |
| `s19a` | 13:58:02Z | `glossary-styles-malformed`               | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/styles.xml` (`styles`), unclosed              | `a2806711c66c6f67` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/styles.xml`, `paraid-missing-element@word/glossary/document.xml`)      |
| `s19a` | 13:58:08Z | `glossary-styles-wellformed-control`      | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/styles.xml` (`styles`), well formed           | `a558cc38b4f31b79` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                             |
| `s19a` | 13:57:52Z | `glossary-settings-malformed`             | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/settings.xml` (`settings`), unclosed          | `8a3b63239dc3bfef` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/settings.xml`, `paraid-missing-element@word/glossary/document.xml`)    |
| `s19a` | 13:57:01Z | `glossary-fonttable-malformed`            | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/fontTable.xml` (`fontTable`), unclosed        | `39eecc758c302f8e` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/fontTable.xml`, `paraid-missing-element@word/glossary/document.xml`)   |
| `s19a` | 13:58:07Z | `glossary-websettings-malformed`          | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/webSettings.xml` (`webSettings`), unclosed    | `302c06953240c800` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/webSettings.xml`, `paraid-missing-element@word/glossary/document.xml`) |
| `s19a` | 13:58:08Z | `s19a-control-minimal-end`                | control    | —                                                                                                                               | `295e6a6b1ee42022` | clean-open     | valid                  | valid                                                                                                     |
| `s19b` | 13:58:33Z | `s19b-control-minimal`                    | control    | —                                                                                                                               | `295e6a6b1ee42022` | clean-open     | valid                  | valid                                                                                                     |
| `s19b` | 13:58:30Z | `glossary-numbering-malformed`            | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/numbering.xml` (`numbering`), unclosed        | `6b449ed507c7de21` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/numbering.xml`, `paraid-missing-element@word/glossary/document.xml`)   |
| `s19b` | 13:58:33Z | `glossary-numbering-wellformed-control`   | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/numbering.xml` (`numbering`), well formed     | `5c935d7377433c83` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                             |
| `s19b` | 13:58:33Z | `glossary-settings-wellformed-control`    | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/settings.xml` (`settings`), well formed       | `66c08103f14382f7` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                             |
| `s19b` | 13:58:33Z | `glossary-fonttable-wellformed-control`   | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/fontTable.xml` (`fontTable`), well formed     | `6fa53cf2a2976787` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                             |
| `s19b` | 13:58:33Z | `glossary-websettings-wellformed-control` | #549 eager | a reached glossary (no story references) whose own `.rels` relates `word/glossary/webSettings.xml` (`webSettings`), well formed | `a28641bef2bf0591` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                             |
| `s19b` | 13:58:33Z | `s19b-control-minimal-end`                | control    | —                                                                                                                               | `19cd78173931a680` | clean-open     | valid                  | valid                                                                                                     |

The four controls are minimal packages; `s19a-control-minimal-end` and `s19b-control-minimal` are byte-identical.

<details><summary>Raw records, session 19</summary>

```jsonl
{"run": "s19a", "name": "s19a-control-minimal", "sha256": "771b090b1d7159c591a72ffc6a49664823e14da5c53af04d49e4f70e0a694c84", "observedAt": "2026-10-24T13:58:08+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19a", "name": "glossary-styles-malformed", "sha256": "a2806711c66c6f67d10817c0e51445b70129657a20e8969c197fc18d7ea8e2ab", "observedAt": "2026-10-24T13:58:02.413Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__glossary-styles-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__glossary-styles-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s19a", "name": "glossary-styles-wellformed-control", "sha256": "a558cc38b4f31b7905a7d53c210084cc20b9f9b088dffc30731c7091b5fef45e", "observedAt": "2026-10-24T13:58:08+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19a", "name": "glossary-settings-malformed", "sha256": "8a3b63239dc3bfefb59c188ad08b2ae766f5c6b738d32db1071b3a8e01eb0124", "observedAt": "2026-10-24T13:57:52.781Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__glossary-settings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__glossary-settings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s19a", "name": "glossary-fonttable-malformed", "sha256": "39eecc758c302f8e3e79751a4a18515cbcbc63d6aa1be1818109657ad5e4798e", "observedAt": "2026-10-24T13:57:01.602Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__glossary-fonttable-malformed.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__glossary-fonttable-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__glossary-fonttable-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s19a", "name": "glossary-websettings-malformed", "sha256": "302c06953240c800106df83889816555b9b45419e806074068e009542558cabd", "observedAt": "2026-10-24T13:58:07.101Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-websettings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-websettings-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s19a", "name": "s19a-control-minimal-end", "sha256": "295e6a6b1ee420220c7ed175740eeb7b3c07f7f13bc8d5f85e8d6d5d9169fb6c", "observedAt": "2026-10-24T13:58:08+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "s19b-control-minimal", "sha256": "295e6a6b1ee420220c7ed175740eeb7b3c07f7f13bc8d5f85e8d6d5d9169fb6c", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "glossary-numbering-malformed", "sha256": "6b449ed507c7de213940bed2ee433149434486766ae6d5bd4523e714b322af31", "observedAt": "2026-10-24T13:58:30.868Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__glossary-numbering-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__glossary-numbering-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s19b", "name": "glossary-numbering-wellformed-control", "sha256": "5c935d7377433c8348972d225c6c3f9769dda9b4fe68b426479d078621ebeec1", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "glossary-settings-wellformed-control", "sha256": "66c08103f14382f7f31c939d01b06645c7f5e58c1ff82f4747db4c1606d3a3ea", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "glossary-fonttable-wellformed-control", "sha256": "6fa53cf2a2976787f43badf42cf1cdbf64e3393896e158461e4b52ad71fc777b", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "glossary-websettings-wellformed-control", "sha256": "a28641bef2bf059180f4d84f66a51ea932c946c399abfa74c229a681e4643016", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s19b", "name": "s19b-control-minimal-end", "sha256": "19cd78173931a680dbd8898262a30f1ede701d4ca8598c5762d33ddfd707a132", "observedAt": "2026-10-24T13:58:33+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 20: 14:28Z–14:30Z, validator columns at 52fdbd8b

The glossary's remaining relationships (#569, #549), a MIME parameter on the remaining Word-read parts (#570), and numbering and theme typed by the generic Default (#571). The glossary specimens are built as in session 19: the minimal package plus `word/glossary/document.xml`, reached through a main-document `glossaryDocument` relationship and referencing no story, whose own relationships part relates one part. Each content-type specimen is the minimal package plus one part related from the main document, used where the type is lazy, and typed by its `Override`, or by the generic Default when it has none.

| Run    | Observed  | Specimen                                            | Issue             | Shape                                                                                                                                                 | SHA-256 (first 16) | Word           | word-valid at 52fdbd8b | strict at 52fdbd8b                                                                                                                                          |
| ------ | --------- | --------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s20a` | 14:28:52Z | `s20a-control-minimal`                              | control           | —                                                                                                                                                     | `1020f1a7be8c2fec` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20a` | 14:28:52Z | `glossary-customxml-malformed`                      | #562              | a reached glossary (no story references) whose own `.rels` relates `customXml/item1.xml` (`customXml`, target `../../customXml/item1.xml`), truncated | `374169fe30287850` | clean-open     | valid                  | invalid (`xml-syntax@customXml/item1.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                             |
| `s20a` | 14:28:52Z | `glossary-customxml-wellformed-control`             | #562              | a reached glossary (no story references) whose own `.rels` relates `customXml/item1.xml` (`customXml`, target `../../customXml/item1.xml`), `<root/>` | `a74f988adc46863b` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                               |
| `s20a` | 14:28:49Z | `glossary-theme-malformed`                          | #562              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`), a Word theme unclosed                  | `d340bf57cba7d2b6` | repair-warning | valid                  | invalid (`xml-syntax@word/glossary/theme/theme1.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                  |
| `s20a` | 14:28:52Z | `glossary-theme-wellformed-control`                 | #562              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`), a Word theme well formed               | `6e7fcd6ed1824423` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                               |
| `s20a` | 14:28:52Z | `glossary-nested-glossary-malformed`                | #562              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/glossary2.xml` (`glossaryDocument`), unclosed                       | `d826f13689630eb2` | clean-open     | valid                  | invalid (`xml-syntax@word/glossary/glossary2.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                     |
| `s20a` | 14:28:52Z | `glossary-nested-glossary-wellformed-control`       | #562              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/glossary2.xml` (`glossaryDocument`), well formed                    | `283ec3b603e59fdd` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                               |
| `s20a` | 14:28:52Z | `s20a-control-minimal-end`                          | control           | —                                                                                                                                                     | `1020f1a7be8c2fec` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20b` | 14:29:39Z | `s20b-control-minimal`                              | control           | —                                                                                                                                                     | `c581427289561aaa` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20b` | 14:29:34Z | `numbering-override-charset`                        | #550              | `word/numbering.xml` related, its `Override` the numbering type plus `; charset=utf-8`                                                                | `130153d7b555e024` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/numbering.xml`)                                                                                               |
| `s20b` | 14:29:39Z | `theme-override-charset`                            | #550              | `word/theme/theme1.xml` related, its `Override` the theme type plus `; charset=utf-8`                                                                 | `aeeb606aa7e7a462` | repair-warning | valid                  | valid                                                                                                                                                       |
| `s20b` | 14:29:39Z | `glossary-override-charset`                         | #550              | `word/glossary/document.xml` related, its `Override` the glossary document type plus `; charset=utf-8`                                                | `1eff4a90ddbea25e` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/glossary/document.xml`, `paraid-missing-element@word/glossary/document.xml`)                                  |
| `s20b` | 14:29:25Z | `footer-override-charset`                           | #550              | `word/footer9.xml` related and referenced from the body `w:sectPr`, its `Override` the footer type plus `; charset=utf-8`                             | `c5675669b5895890` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/footer9.xml`, `paraid-missing-element@word/footer9.xml`)                                                      |
| `s20b` | 14:29:30Z | `footnotes-override-charset`                        | #550              | `word/footnotes.xml` related and referenced (`w:footnoteReference`), its `Override` the footnotes type plus `; charset=utf-8`                         | `d17691b311cf5133` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/footnotes.xml`, `paraid-missing-element@word/footnotes.xml`)                                                  |
| `s20b` | 14:29:21Z | `endnotes-override-charset`                         | #550              | `word/endnotes.xml` related and referenced (`w:endnoteReference`), its `Override` the endnotes type plus `; charset=utf-8`                            | `f848c4a5da569833` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/endnotes.xml`, `paraid-missing-element@word/endnotes.xml`)                                                    |
| `s20b` | 14:29:39Z | `s20b-control-minimal-end`                          | control           | —                                                                                                                                                     | `c581427289561aaa` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20c` | 14:30:09Z | `s20c-control-minimal`                              | control           | —                                                                                                                                                     | `c581427289561aaa` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20c` | 14:30:00Z | `comments-override-charset`                         | #550              | `word/comments.xml` related and referenced (`w:commentReference`), its `Override` the comments type plus `; charset=utf-8`                            | `937c2eff89592e7d` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/comments.xml`, `comment-thread-count-mismatch@word/document.xml`, `paraid-missing-element@word/comments.xml`) |
| `s20c` | 14:30:09Z | `glossary-footnotes-related-unreferenced-malformed` | #549              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/footnotes.xml` (`footnotes`), not referenced, unclosed              | `053af8bdb0747097` | clean-open     | valid                  | invalid (`xml-syntax@word/glossary/footnotes.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                     |
| `s20c` | 14:30:09Z | `glossary-endnotes-related-unreferenced-malformed`  | #549              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/endnotes.xml` (`endnotes`), not referenced, unclosed                | `a02919bf95888214` | clean-open     | valid                  | invalid (`xml-syntax@word/glossary/endnotes.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                      |
| `s20c` | 14:30:09Z | `glossary-comments-related-unreferenced-malformed`  | #549              | a reached glossary (no story references) whose own `.rels` relates `word/glossary/comments.xml` (`comments`), not referenced, unclosed                | `abc9dd306767c4af` | clean-open     | valid                  | invalid (`xml-syntax@word/glossary/comments.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                      |
| `s20c` | 14:30:04Z | `numbering-default-generic`                         | #432              | `word/numbering.xml` related, no `Override`: typed by `Default Extension="xml" ContentType="application/xml"`                                         | `62e667ff418ada7f` | repair-warning | valid                  | invalid (`word-part-content-type-generic@word/numbering.xml`)                                                                                               |
| `s20c` | 14:30:08Z | `theme-default-generic`                             | #432              | `word/theme/theme1.xml` related, no `Override`: typed by `Default Extension="xml" ContentType="application/xml"`                                      | `1d1542b626811c84` | repair-warning | valid                  | invalid (`ct-undeclared-part@word/theme/theme1.xml`)                                                                                                        |
| `s20c` | 14:30:09Z | `s20c-control-minimal-end`                          | control           | —                                                                                                                                                     | `c581427289561aaa` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20d` | 14:30:23Z | `s20d-control-minimal`                              | control           | —                                                                                                                                                     | `30b8f1c2ce0a79f8` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20d` | 14:30:23Z | `numbering-override-exact-control`                  | #550 #432 control | `word/numbering.xml` related, its `Override` the exact numbering type                                                                                 | `4c23ed6449caea9d` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20d` | 14:30:23Z | `theme-override-exact-control`                      | #550 #432 control | `word/theme/theme1.xml` related, its `Override` the exact theme type                                                                                  | `57705296e7f9381b` | clean-open     | valid                  | valid                                                                                                                                                       |
| `s20d` | 14:30:23Z | `glossary-override-exact-control`                   | #550 control      | `word/glossary/document.xml` related, its `Override` the exact glossary document type                                                                 | `5d3be5b7d10210ca` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                               |
| `s20d` | 14:30:23Z | `footer-override-exact-control`                     | #550 control      | `word/footer9.xml` related and referenced from the body `w:sectPr`, its `Override` the exact footer type                                              | `1600256784ae396a` | clean-open     | valid                  | invalid (`paraid-missing-element@word/footer9.xml`)                                                                                                         |
| `s20d` | 14:30:23Z | `footnotes-override-exact-control`                  | #550 control      | `word/footnotes.xml` related and referenced (`w:footnoteReference`), its `Override` the exact footnotes type                                          | `e4bbe5bdce633dc1` | clean-open     | valid                  | invalid (`paraid-missing-element@word/footnotes.xml`)                                                                                                       |
| `s20d` | 14:30:23Z | `endnotes-override-exact-control`                   | #550 control      | `word/endnotes.xml` related and referenced (`w:endnoteReference`), its `Override` the exact endnotes type                                             | `059d4d8947301578` | clean-open     | valid                  | invalid (`paraid-missing-element@word/endnotes.xml`)                                                                                                        |
| `s20d` | 14:30:23Z | `comments-override-exact-control`                   | #550 control      | `word/comments.xml` related and referenced (`w:commentReference`), its `Override` the exact comments type                                             | `d9fdd2fe5ef39b38` | clean-open     | valid                  | invalid (`comment-thread-count-mismatch@word/document.xml`, `paraid-missing-element@word/comments.xml`)                                                     |

The `s20a` controls are byte-identical, and so are the `s20b` and `s20c` controls.

<details><summary>Raw records, session 20</summary>

```jsonl
{"run": "s20a", "name": "s20a-control-minimal", "sha256": "1020f1a7be8c2fecd2e6428df8756b987230ed8219fe970e738b41ed147892fa", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "glossary-customxml-malformed", "sha256": "374169fe302878502fcdcaf57f993a1f1dcd0a967953c8097aa952b5c680866e", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "glossary-customxml-wellformed-control", "sha256": "a74f988adc46863b6e34d1af3f0acb91bbb0d6c4130bef75d99e970b65566539", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "glossary-theme-malformed", "sha256": "d340bf57cba7d2b6a1811555eb5b5f11fe5f6d35a057306c8baa3cea3167a2bd", "observedAt": "2026-10-24T14:28:49.951Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-theme-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-theme-malformed.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20a", "name": "glossary-theme-wellformed-control", "sha256": "6e7fcd6ed1824423c61356b847a709ce9937b72a92f2f72098b2232c0617d709", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "glossary-nested-glossary-malformed", "sha256": "d826f13689630eb2a176ca58cb222e1f743891bef96017bef29c30e7b59fb1b8", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "glossary-nested-glossary-wellformed-control", "sha256": "283ec3b603e59fdd57e5ee088a8206c353e065f89b52f9dd8364db512561cc9f", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20a", "name": "s20a-control-minimal-end", "sha256": "1020f1a7be8c2fecd2e6428df8756b987230ed8219fe970e738b41ed147892fa", "observedAt": "2026-10-24T14:28:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20b", "name": "s20b-control-minimal", "sha256": "c581427289561aaa7e44e315c782466442a3f050bb4f551a83abd192c25678df", "observedAt": "2026-10-24T14:29:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20b", "name": "numbering-override-charset", "sha256": "130153d7b555e02455ba2366c347dda7ec8736ed0c39cd5c74edd7d678b1eea5", "observedAt": "2026-10-24T14:29:34.434Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__numbering-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__numbering-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20b", "name": "theme-override-charset", "sha256": "aeeb606aa7e7a462056196944654ec3ad426c0082b75bbeb734de1cc7cf94c95", "observedAt": "2026-10-24T14:29:39.086Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__theme-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__theme-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20b", "name": "glossary-override-charset", "sha256": "1eff4a90ddbea25ea5414c64c482b39baf97830dd1faf260c9b9a4fbf8b454e0", "observedAt": "2026-10-24T14:29:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20b", "name": "footer-override-charset", "sha256": "c5675669b58958900c126fab4936241c2de0b3964bcca46a6de013c2c1dbaf5f", "observedAt": "2026-10-24T14:29:25.900Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__footer-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__footer-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20b", "name": "footnotes-override-charset", "sha256": "d17691b311cf5133d564abd7d668c2798a51734a420d530ae819505f32fbf863", "observedAt": "2026-10-24T14:29:30.067Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__footnotes-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__footnotes-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20b", "name": "endnotes-override-charset", "sha256": "f848c4a5da569833ba17c2c6c90ba8ec1f1620c0cc9b2cafbfa09b6278d3dbc7", "observedAt": "2026-10-24T14:29:21.726Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__endnotes-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__endnotes-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20b", "name": "s20b-control-minimal-end", "sha256": "c581427289561aaa7e44e315c782466442a3f050bb4f551a83abd192c25678df", "observedAt": "2026-10-24T14:29:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20c", "name": "s20c-control-minimal", "sha256": "c581427289561aaa7e44e315c782466442a3f050bb4f551a83abd192c25678df", "observedAt": "2026-10-24T14:30:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20c", "name": "comments-override-charset", "sha256": "937c2eff89592e7dfb283fe6d3972e0319df731ba4ea3bd03ba56f7e28d846c5", "observedAt": "2026-10-24T14:30:00.168Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__comments-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__comments-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20c", "name": "glossary-footnotes-related-unreferenced-malformed", "sha256": "053af8bdb0747097a7d4ebc79eff3bc9cac7ab82e2d6a0508029324648c3a1fd", "observedAt": "2026-10-24T14:30:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20c", "name": "glossary-endnotes-related-unreferenced-malformed", "sha256": "a02919bf958882149da06eed56b515853cb2415a07e73f23065a32d2b218c2c0", "observedAt": "2026-10-24T14:30:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20c", "name": "glossary-comments-related-unreferenced-malformed", "sha256": "abc9dd306767c4af0342ac55ef9f1fe2824f7f0da22a8102a606f31df22527e0", "observedAt": "2026-10-24T14:30:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20c", "name": "numbering-default-generic", "sha256": "62e667ff418ada7fbc6868f20eab666b0605bf9af568137e4fafbd1489663f3f", "observedAt": "2026-10-24T14:30:04.550Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__numbering-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__numbering-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20c", "name": "theme-default-generic", "sha256": "1d1542b626811c84fcb9155b2784c3fecebfe2d95c836a0e938f9e0dec0ec622", "observedAt": "2026-10-24T14:30:08.801Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__theme-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__theme-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s20c", "name": "s20c-control-minimal-end", "sha256": "c581427289561aaa7e44e315c782466442a3f050bb4f551a83abd192c25678df", "observedAt": "2026-10-24T14:30:09+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "s20d-control-minimal", "sha256": "30b8f1c2ce0a79f8f411a537a0ea5e79f79890c1126672791e6ca706b672cb72", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "numbering-override-exact-control", "sha256": "4c23ed6449caea9de1b7d168cc7f7d51488a28530882eb562ade044d4de439cd", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "theme-override-exact-control", "sha256": "57705296e7f9381bda6e5c35ee470e554b827c0fb6a32456af1c3fe5af2bae06", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "glossary-override-exact-control", "sha256": "5d3be5b7d10210ca687a89b9fe6456ed8d3b8ffab1fbe52d305ba9c847e7804d", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "footer-override-exact-control", "sha256": "1600256784ae396aedef701cce4a3c825c18ae82840576385045f22df7e0b496", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "footnotes-override-exact-control", "sha256": "e4bbe5bdce633dc17919d9f7f0fd604a3a3d53584c1a9ea7a95c407036104425", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "endnotes-override-exact-control", "sha256": "059d4d894730157852c96ea91d6bd3808cfe7dbf0e1338429e281ead28a93a5b", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s20d", "name": "comments-override-exact-control", "sha256": "d9fdd2fe5ef39b386c9dd2c1f94ad64093cc5fb29a32342aa2d634873f1bba1a", "observedAt": "2026-10-24T14:30:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 21: 14:43Z–14:44Z, validator columns at cb36e27a

What session 20 left open for #570 — a trailing space on the six parts it refused with a parameter, and a parameter on related but unused lazy parts — and a parameter on the styles part a reached glossary relates (#579). The used and unused parts are built as in session 20; the glossary specimens as in session 19.

| Run    | Observed  | Specimen                                 | Issue             | Shape                                                                                                                                                                            | SHA-256 (first 16) | Word           | word-valid at cb36e27a | strict at cb36e27a                                                                                                                                                                                                              |
| ------ | --------- | ---------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s21a` | 14:43:43Z | `s21a-control-minimal`                   | control           | —                                                                                                                                                                                | `2843331dff62f878` | clean-open     | valid                  | valid                                                                                                                                                                                                                           |
| `s21a` | 14:43:32Z | `numbering-override-padded`              | #570              | the main document relates and uses `word/numbering.xml` (eager), typed by an `Override` carrying its own type plus a trailing space                                              | `53da7829b20061c7` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/numbering.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                                                               |
| `s21a` | 14:43:38Z | `theme-override-padded`                  | #570              | the main document relates and uses `word/theme/theme1.xml` (eager), typed by an `Override` carrying its own type plus a trailing space                                           | `085d464ef2ae5c7b` | repair-warning | valid                  | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                                                                                                                    |
| `s21a` | 14:43:17Z | `footer-override-padded`                 | #570              | the main document relates and uses `word/footer9.xml` (body `w:sectPr` `w:footerReference`), typed by an `Override` carrying its own type plus a trailing space                  | `130c534cf52b6fc4` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/footer9.xml`, `paraid-missing-element@word/footer9.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                      |
| `s21a` | 14:43:22Z | `footnotes-override-padded`              | #570              | the main document relates and uses `word/footnotes.xml` (`w:footnoteReference`), typed by an `Override` carrying its own type plus a trailing space                              | `c5db1f85c0882d1a` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/footnotes.xml`, `paraid-missing-element@word/footnotes.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                  |
| `s21a` | 14:43:07Z | `endnotes-override-padded`               | #570              | the main document relates and uses `word/endnotes.xml` (`w:endnoteReference`), typed by an `Override` carrying its own type plus a trailing space                                | `ffa3212c76bdf562` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/endnotes.xml`, `paraid-missing-element@word/endnotes.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                    |
| `s21a` | 14:43:03Z | `comments-override-padded`               | #570              | the main document relates and uses `word/comments.xml` (`w:commentReference`), typed by an `Override` carrying its own type plus a trailing space                                | `944e2396d814f0dd` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/comments.xml`, `comment-thread-count-mismatch@word/document.xml`, `paraid-missing-element@word/comments.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s21a` | 14:43:43Z | `s21a-control-minimal-end`               | control           | —                                                                                                                                                                                | `2843331dff62f878` | clean-open     | valid                  | valid                                                                                                                                                                                                                           |
| `s21b` | 14:44:52Z | `s21b-control-minimal`                   | control           | —                                                                                                                                                                                | `2843331dff62f878` | clean-open     | valid                  | valid                                                                                                                                                                                                                           |
| `s21b` | 14:44:52Z | `footer-unused-override-charset`         | #570              | the main document relates `word/footer9.xml` but never references it, typed by an `Override` carrying its own type plus `; charset=utf-8`                                        | `226a58854292038f` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/footer9.xml`, `paraid-missing-element@word/footer9.xml`)                                                                                                                          |
| `s21b` | 14:44:52Z | `footnotes-unused-override-charset`      | #570              | the main document relates `word/footnotes.xml` but never references it, typed by an `Override` carrying its own type plus `; charset=utf-8`                                      | `8a047cfb83325c64` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/footnotes.xml`, `paraid-missing-element@word/footnotes.xml`)                                                                                                                      |
| `s21b` | 14:44:52Z | `endnotes-unused-override-charset`       | #570              | the main document relates `word/endnotes.xml` but never references it, typed by an `Override` carrying its own type plus `; charset=utf-8`                                       | `0d8a6fe212923e0e` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/endnotes.xml`, `paraid-missing-element@word/endnotes.xml`)                                                                                                                        |
| `s21b` | 14:44:52Z | `comments-unused-override-charset`       | #570              | the main document relates `word/comments.xml` but never references it, typed by an `Override` carrying its own type plus `; charset=utf-8`                                       | `a7a09482d0728dff` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/comments.xml`, `comment-thread-count-mismatch@word/document.xml`, `paraid-missing-element@word/comments.xml`)                                                                     |
| `s21b` | 14:44:52Z | `header-unused-override-charset`         | #570              | the main document relates `word/header9.xml` but never references it, typed by an `Override` carrying its own type plus `; charset=utf-8`                                        | `494f823684d5be13` | clean-open     | valid                  | invalid (`word-part-content-type-inexact@word/header9.xml`, `paraid-missing-element@word/header9.xml`)                                                                                                                          |
| `s21b` | 14:44:50Z | `glossary-styles-override-charset`       | #570 #562         | a reached glossary (no story references) whose own `.rels` relates `word/glossary/styles.xml` (`styles`), typed by an `Override` carrying the styles type plus `; charset=utf-8` | `2d9088df00b55c0b` | repair-warning | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                                   |
| `s21b` | 14:44:52Z | `glossary-styles-override-exact-control` | #570 #562 control | a reached glossary (no story references) whose own `.rels` relates `word/glossary/styles.xml` (`styles`), typed by an `Override` carrying the exact styles type                  | `69d312039c3ade9f` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                                   |

The `s21a` and `s21b` controls are byte-identical.

<details><summary>Raw records, session 21</summary>

```jsonl
{"run": "s21a", "name": "s21a-control-minimal", "sha256": "2843331dff62f87825068c059b8f1a6e2c0531c8784355af1e6b0f2ae2e60716", "observedAt": "2026-10-24T14:43:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21a", "name": "numbering-override-padded", "sha256": "53da7829b20061c7aff1f18f4cb7e563376e438c5cb124eae3802cbf7cc30992", "observedAt": "2026-10-24T14:43:32.064Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__numbering-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__numbering-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "theme-override-padded", "sha256": "085d464ef2ae5c7bd3b6ac2287ce7c2e0fed9a59e0852ae1bb4c36e506881535", "observedAt": "2026-10-24T14:43:38.216Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00007__wfv__theme-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__theme-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "footer-override-padded", "sha256": "130c534cf52b6fc4bccf8a3a75cb648188567ef5c37bb3829e929d362e85bc66", "observedAt": "2026-10-24T14:43:17.709Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__footer-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__footer-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "footnotes-override-padded", "sha256": "c5db1f85c0882d1a533494072446dc47e744c555690327e6a524647593a06530", "observedAt": "2026-10-24T14:43:22.008Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__footnotes-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__footnotes-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "endnotes-override-padded", "sha256": "ffa3212c76bdf5627f476982a6e3f24020d22be177eda24024062720aabd6707", "observedAt": "2026-10-24T14:43:07.716Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__endnotes-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__endnotes-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "comments-override-padded", "sha256": "944e2396d814f0dd579a53e83feb3ba19139217182aadabfb823dc215e638a33", "observedAt": "2026-10-24T14:43:03.437Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__comments-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__comments-override-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21a", "name": "s21a-control-minimal-end", "sha256": "2843331dff62f87825068c059b8f1a6e2c0531c8784355af1e6b0f2ae2e60716", "observedAt": "2026-10-24T14:43:43+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "s21b-control-minimal", "sha256": "2843331dff62f87825068c059b8f1a6e2c0531c8784355af1e6b0f2ae2e60716", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "footer-unused-override-charset", "sha256": "226a58854292038fa4a394c5a43715af0e011ed1820c5d8bfb436fd55fe2299a", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "footnotes-unused-override-charset", "sha256": "8a047cfb83325c643b35f1d3fab742714b55b239694eecefebd697e5e6635d00", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "endnotes-unused-override-charset", "sha256": "0d8a6fe212923e0ebf58e4fb1121d562c5cc59edca7fec58ee4dcb4e9366330f", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "comments-unused-override-charset", "sha256": "a7a09482d0728dff81a242219dc8e9025bd099da2e5b41055c7c5c37a83d11fb", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "header-unused-override-charset", "sha256": "494f823684d5be137cff525a21e8dfbb240fe2c21660e685fed50246529f882b", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s21b", "name": "glossary-styles-override-charset", "sha256": "2d9088df00b55c0b5a5e78c542797d66f18371321718912d1ffae75b7e50ca13", "observedAt": "2026-10-24T14:44:50.240Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-styles-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-styles-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s21b", "name": "glossary-styles-override-exact-control", "sha256": "69d312039c3ade9faf9e27e44e2b2b002b886153bc9e33e2fff69f74958e9052", "observedAt": "2026-10-24T14:44:52+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 22: 14:48Z–14:48Z, validator columns at cb36e27a

The items adversarial review AU suspected at layer 109 (ledger on #550): S1, S2, S4, S5 and S6, each with its control. S3, a parameter on the glossary part itself, was already observed in session 20 (`glossary-override-charset`, clean). The glossary header specimens are built as in session 16, with `mc` and `w14` declared on the glossary root.

| Run    | Observed  | Specimen                                           | Issue         | Shape                                                                                                                                                                                                                                                                         | SHA-256 (first 16) | Word           | word-valid at cb36e27a                                       | strict at cb36e27a                                                                                                             |
| ------ | --------- | -------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `s22a` | 14:48:23Z | `s22a-control-minimal`                             | control       | —                                                                                                                                                                                                                                                                             | `4493c501d3ad343f` | clean-open     | valid                                                        | valid                                                                                                                          |
| `s22a` | 14:48:21Z | `glossary-header-override-charset`                 | AU-S1         | a reached glossary whose `docPartBody` ends with a `w:sectPr` that references `word/glossary/header9.xml` (related by the glossary's own `.rels`) directly; the header is well formed and its `Override` carries the header type plus `; charset=utf-8`                       | `5bbf84b1398e8b64` | repair-warning | valid                                                        | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`)              |
| `s22a` | 14:48:23Z | `glossary-header-override-exact-control`           | AU-S1 control | a reached glossary whose `docPartBody` ends with a `w:sectPr` that references `word/glossary/header9.xml` (related by the glossary's own `.rels`) directly; the header is well formed and its `Override` carries the exact header type                                        | `dd88ab6682464259` | clean-open     | valid                                                        | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`)              |
| `s22a` | 14:48:23Z | `glossary-header-fallback-only-malformed`          | AU-S6         | a reached glossary whose `docPartBody` ends with a `w:sectPr` that references `word/glossary/header9.xml` (related by the glossary's own `.rels`) only inside the `mc:Fallback` of an `mc:AlternateContent` whose `mc:Choice Requires="w14"` is empty; the header is unclosed | `938dd46f83fdf18b` | clean-open     | valid                                                        | invalid (`xml-syntax@word/glossary/header9.xml`, `paraid-missing-element@word/glossary/document.xml`)                          |
| `s22a` | 14:48:16Z | `glossary-header-choice-only-malformed-control`    | AU-S6 control | a reached glossary whose `docPartBody` ends with a `w:sectPr` that references `word/glossary/header9.xml` (related by the glossary's own `.rels`) only inside the `mc:Choice Requires="w14"` (empty `mc:Fallback`); the header is unclosed                                    | `4aa67a7663bf88fc` | repair-warning | invalid (`xml-syntax@word/glossary/header9.xml`)             | invalid (`xml-syntax@word/glossary/header9.xml`, `paraid-missing-element@word/glossary/document.xml`)                          |
| `s22a` | 14:48:23Z | `glossary-header-fallback-only-wellformed-control` | AU-S6 control | a reached glossary whose `docPartBody` ends with a `w:sectPr` that references `word/glossary/header9.xml` (related by the glossary's own `.rels`) only inside the `mc:Fallback`, as above; the header is well formed                                                          | `137569bb50d059b7` | clean-open     | valid                                                        | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/header9.xml`)              |
| `s22a` | 14:48:23Z | `s22a-control-minimal-end`                         | control       | —                                                                                                                                                                                                                                                                             | `4493c501d3ad343f` | clean-open     | valid                                                        | valid                                                                                                                          |
| `s22b` | 14:48:50Z | `s22b-control-minimal`                             | control       | —                                                                                                                                                                                                                                                                             | `4493c501d3ad343f` | clean-open     | valid                                                        | valid                                                                                                                          |
| `s22b` | 14:48:36Z | `main-override-empty-contenttype`                  | AU-S2         | the main document's `Override` has `ContentType=""`                                                                                                                                                                                                                           | `2c80b41c04c33aae` | repair-warning | valid                                                        | invalid (`xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`)                                                   |
| `s22b` | 14:48:49Z | `styles-override-nbsp-trailing`                    | AU-S4         | the styles `Override` carries the styles type plus a trailing U+00A0 NO-BREAK SPACE                                                                                                                                                                                           | `d8dbef2af503bb71` | repair-warning | invalid (`word-part-content-type-inexact@word/styles.xml`)   | invalid (`word-part-content-type-inexact@word/styles.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s22b` | 14:48:45Z | `styles-override-ascii-trailing-space-control`     | AU-S4 control | the styles `Override` carries the styles type plus a trailing U+0020 SPACE                                                                                                                                                                                                    | `6eca487f02310dc7` | repair-warning | invalid (`word-part-content-type-inexact@word/styles.xml`)   | invalid (`word-part-content-type-inexact@word/styles.xml`, `xsd-summary@[Content_Types].xml`, `xsd-error@[Content_Types].xml`) |
| `s22b` | 14:48:41Z | `main-override-upper-charset-upper`                | AU-S5         | the main document's `Override` carries the main type upper-cased plus `; CHARSET=UTF-8`                                                                                                                                                                                       | `eee9266e35b7c734` | repair-warning | invalid (`word-part-content-type-inexact@word/document.xml`) | invalid (`word-part-content-type-inexact@word/document.xml`)                                                                   |
| `s22b` | 14:48:50Z | `main-override-upper-control`                      | AU-S5 control | the main document's `Override` carries the main type upper-cased                                                                                                                                                                                                              | `c9f80aa7ea7740be` | clean-open     | valid                                                        | valid                                                                                                                          |
| `s22b` | 14:48:50Z | `s22b-control-minimal-end`                         | control       | —                                                                                                                                                                                                                                                                             | `4493c501d3ad343f` | clean-open     | valid                                                        | valid                                                                                                                          |

The `s22a` and `s22b` controls are byte-identical.

<details><summary>Raw records, session 22</summary>

```jsonl
{"run": "s22a", "name": "s22a-control-minimal", "sha256": "4493c501d3ad343f7f3d72cd70cb4efb8ccf149ec53c15acf011b1f9bcbb4a81", "observedAt": "2026-10-24T14:48:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22a", "name": "glossary-header-override-charset", "sha256": "5bbf84b1398e8b64d2d12da33ecf3bb4516dc34a04866619f7fa2f4b1d84101f", "observedAt": "2026-10-24T14:48:21.057Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__glossary-header-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__glossary-header-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22a", "name": "glossary-header-override-exact-control", "sha256": "dd88ab668246425920a80f8c8cc3a8c04e3e876baed0e5179e2aa591639581cb", "observedAt": "2026-10-24T14:48:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22a", "name": "glossary-header-fallback-only-malformed", "sha256": "938dd46f83fdf18b68714c0733df2d8b831da06c8439c429a126d35053806210", "observedAt": "2026-10-24T14:48:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22a", "name": "glossary-header-choice-only-malformed-control", "sha256": "4aa67a7663bf88fc8a78015ecd9c9382a23d736847889dca47ad48efb4f84881", "observedAt": "2026-10-24T14:48:16.692Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__glossary-header-choice-only-malformed-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__glossary-header-choice-only-malformed-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22a", "name": "glossary-header-fallback-only-wellformed-control", "sha256": "137569bb50d059b7a13eacca349a371e2d9a5dea1a44c2964e3260b870281060", "observedAt": "2026-10-24T14:48:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22a", "name": "s22a-control-minimal-end", "sha256": "4493c501d3ad343f7f3d72cd70cb4efb8ccf149ec53c15acf011b1f9bcbb4a81", "observedAt": "2026-10-24T14:48:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22b", "name": "s22b-control-minimal", "sha256": "4493c501d3ad343f7f3d72cd70cb4efb8ccf149ec53c15acf011b1f9bcbb4a81", "observedAt": "2026-10-24T14:48:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22b", "name": "main-override-empty-contenttype", "sha256": "2c80b41c04c33aae13605f62685d2c5de753aa8b828326879291fc4fea3aa7ad", "observedAt": "2026-10-24T14:48:36.923Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__main-override-empty-contenttype.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__main-override-empty-contenttype.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22b", "name": "styles-override-nbsp-trailing", "sha256": "d8dbef2af503bb71a8a386cbc00de551141b25379db191a520f84ba70bdb701a", "observedAt": "2026-10-24T14:48:49.589Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00006__wfv__styles-override-nbsp-trailing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00006__wfv__styles-override-nbsp-trailing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22b", "name": "styles-override-ascii-trailing-space-control", "sha256": "6eca487f02310dc73079260b580be68e33fac35bfc5a2fb6711a5aa89ee8f257", "observedAt": "2026-10-24T14:48:45.426Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__styles-override-ascii-trailing-space-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__styles-override-ascii-trailing-space-control.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22b", "name": "main-override-upper-charset-upper", "sha256": "eee9266e35b7c7341b040c61a7ddcdece31cdefb4da4ddc09c48e63c33035bb0", "observedAt": "2026-10-24T14:48:41.091Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__main-override-upper-charset-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__main-override-upper-charset-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s22b", "name": "main-override-upper-control", "sha256": "c9f80aa7ea7740be2a47c5cc1a9237f13481c48d7080342b22337fbf93cdfe28", "observedAt": "2026-10-24T14:48:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s22b", "name": "s22b-control-minimal-end", "sha256": "4493c501d3ad343f7f3d72cd70cb4efb8ccf149ec53c15acf011b1f9bcbb4a81", "observedAt": "2026-10-24T14:48:50+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 23: 16:12Z–16:13Z, validator columns at 8690b11c

The items adversarial review AW suspected at layer 123 (ledger on #591): S1 (#595) and S2 (#596), each with its exact-type control. The glossary story specimens are built as in session 17, and the glossary theme specimen as in session 20.

| Run    | Observed  | Specimen                                        | Issue        | Shape                                                                                                                                                                                                                                                                              | SHA-256 (first 16) | Word           | word-valid at 8690b11c | strict at 8690b11c                                                                                                                                                                                                                          |
| ------ | --------- | ----------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s23a` | 16:12:42Z | `s23a-control-minimal`                          | control      | —                                                                                                                                                                                                                                                                                  | `261061f455b57873` | clean-open     | valid                  | valid                                                                                                                                                                                                                                       |
| `s23a` | 16:12:39Z | `glossary-theme-default-generic`                | #595         | a reached glossary that references no story, whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`); the theme is session 20's well-formed theme and has no `Override`, so the generic `Default Extension="xml" ContentType="application/xml"` types it              | `5b998938325a4005` | repair-warning | valid                  | invalid (`ct-undeclared-part@word/glossary/theme/theme1.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                                                                                          |
| `s23a` | 16:12:42Z | `glossary-theme-override-exact-control`         | #595 control | a reached glossary that references no story, whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`); the theme is session 20's well-formed theme and its `Override` carries the exact theme type                                                                     | `ec97fc5736d30c05` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                                                                                                                               |
| `s23a` | 16:12:35Z | `glossary-footer-ref-override-charset`          | #596         | a reached glossary that references `word/glossary/footer9.xml` through `w:footerReference` in the `w:sectPr` ending its `docPartBody`, related by the glossary's own `.rels` (`footer`); the part is well formed and its `Override` carries the footer type plus `; charset=utf-8` | `730f773d3a828c26` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/glossary/footer9.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)                                                               |
| `s23a` | 16:12:42Z | `glossary-footer-ref-override-exact-control`    | #596 control | a reached glossary that references `word/glossary/footer9.xml` through `w:footerReference` in the `w:sectPr` ending its `docPartBody`, related by the glossary's own `.rels` (`footer`); the part is well formed and its `Override` carries the exact footer type                  | `0e8c978df8c12b47` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)                                                                                                                           |
| `s23a` | 16:12:30Z | `glossary-comments-ref-override-charset`        | #596         | a reached glossary that references `word/glossary/comments.xml` through `w:commentReference` in its `docPartBody`, related by the glossary's own `.rels` (`comments`); the part is well formed and its `Override` carries the comments type plus `; charset=utf-8`                 | `434275cc3942627e` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/glossary/comments.xml`, `comment-thread-count-mismatch@word/glossary/document.xml`, `paraid-missing-element@word/glossary/comments.xml`, `paraid-missing-element@word/glossary/document.xml`) |
| `s23a` | 16:12:42Z | `glossary-comments-ref-override-exact-control`  | #596 control | a reached glossary that references `word/glossary/comments.xml` through `w:commentReference` in its `docPartBody`, related by the glossary's own `.rels` (`comments`); the part is well formed and its `Override` carries the exact comments type                                  | `10d1c3234974c153` | clean-open     | valid                  | invalid (`comment-thread-count-mismatch@word/glossary/document.xml`, `paraid-missing-element@word/glossary/comments.xml`, `paraid-missing-element@word/glossary/document.xml`)                                                              |
| `s23a` | 16:12:42Z | `s23a-control-minimal-end`                      | control      | —                                                                                                                                                                                                                                                                                  | `261061f455b57873` | clean-open     | valid                  | valid                                                                                                                                                                                                                                       |
| `s23b` | 16:13:05Z | `s23b-control-minimal`                          | control      | —                                                                                                                                                                                                                                                                                  | `261061f455b57873` | clean-open     | valid                  | valid                                                                                                                                                                                                                                       |
| `s23b` | 16:13:02Z | `glossary-footnotes-ref-override-charset`       | #596         | a reached glossary that references `word/glossary/footnotes.xml` through `w:footnoteReference` in its `docPartBody`, related by the glossary's own `.rels` (`footnotes`); the part is well formed and its `Override` carries the footnotes type plus `; charset=utf-8`             | `bb2a88d66e61c2a3` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/glossary/footnotes.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footnotes.xml`)                                                           |
| `s23b` | 16:13:05Z | `glossary-footnotes-ref-override-exact-control` | #596 control | a reached glossary that references `word/glossary/footnotes.xml` through `w:footnoteReference` in its `docPartBody`, related by the glossary's own `.rels` (`footnotes`); the part is well formed and its `Override` carries the exact footnotes type                              | `12d5af27eb2f7101` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footnotes.xml`)                                                                                                                         |
| `s23b` | 16:12:58Z | `glossary-endnotes-ref-override-charset`        | #596         | a reached glossary that references `word/glossary/endnotes.xml` through `w:endnoteReference` in its `docPartBody`, related by the glossary's own `.rels` (`endnotes`); the part is well formed and its `Override` carries the endnotes type plus `; charset=utf-8`                 | `5483e41dc53d58d9` | repair-warning | valid                  | invalid (`word-part-content-type-inexact@word/glossary/endnotes.xml`, `paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/endnotes.xml`)                                                             |
| `s23b` | 16:13:05Z | `glossary-endnotes-ref-override-exact-control`  | #596 control | a reached glossary that references `word/glossary/endnotes.xml` through `w:endnoteReference` in its `docPartBody`, related by the glossary's own `.rels` (`endnotes`); the part is well formed and its `Override` carries the exact endnotes type                                  | `de68a75da0b11ec6` | clean-open     | valid                  | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/endnotes.xml`)                                                                                                                          |
| `s23b` | 16:13:05Z | `s23b-control-minimal-end`                      | control      | —                                                                                                                                                                                                                                                                                  | `261061f455b57873` | clean-open     | valid                  | valid                                                                                                                                                                                                                                       |

The `s23a` and `s23b` controls are byte-identical.

<details><summary>Raw records, session 23</summary>

```jsonl
{"run": "s23a", "name": "s23a-control-minimal", "sha256": "261061f455b57873fd15855488e7cb8b68dff00396809de74c7fffa5edda65a0", "observedAt": "2026-10-24T16:12:42+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23a", "name": "glossary-theme-default-generic", "sha256": "5b998938325a400549d2611922a596c54eb4a1d78df8468297865a96464f9bdc", "observedAt": "2026-10-24T16:12:39.599Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-theme-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-theme-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s23a", "name": "glossary-theme-override-exact-control", "sha256": "ec97fc5736d30c05d4360905e9b82b2850cd6fddc05709946594d8e0ccf145a1", "observedAt": "2026-10-24T16:12:42+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23a", "name": "glossary-footer-ref-override-charset", "sha256": "730f773d3a828c266c269eef6c8342d8742c5c2f9ea84486d2b6b7b33b963ac9", "observedAt": "2026-10-24T16:12:35.049Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__glossary-footer-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__glossary-footer-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s23a", "name": "glossary-footer-ref-override-exact-control", "sha256": "0e8c978df8c12b47c903836a1ead7517ce1c74dd8a38b0eb82ef2b8cf3df0cf3", "observedAt": "2026-10-24T16:12:42+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23a", "name": "glossary-comments-ref-override-charset", "sha256": "434275cc3942627eb97556a5c09c0e5ec53cbdf56386654f3a9961c81d9468c4", "observedAt": "2026-10-24T16:12:30.473Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__glossary-comments-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__glossary-comments-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s23a", "name": "glossary-comments-ref-override-exact-control", "sha256": "10d1c3234974c1534241b25723861ca5cce8bce7da507e63f2bcf7d1d335eeac", "observedAt": "2026-10-24T16:12:42+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23a", "name": "s23a-control-minimal-end", "sha256": "261061f455b57873fd15855488e7cb8b68dff00396809de74c7fffa5edda65a0", "observedAt": "2026-10-24T16:12:42+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23b", "name": "s23b-control-minimal", "sha256": "261061f455b57873fd15855488e7cb8b68dff00396809de74c7fffa5edda65a0", "observedAt": "2026-10-24T16:13:05+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23b", "name": "glossary-footnotes-ref-override-charset", "sha256": "bb2a88d66e61c2a36e13f3420a12248a2d1f8356787c323d5ebd0c620a7839b4", "observedAt": "2026-10-24T16:13:02.934Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__glossary-footnotes-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__glossary-footnotes-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s23b", "name": "glossary-footnotes-ref-override-exact-control", "sha256": "12d5af27eb2f7101c8daf5c48f271d174281c3aa5d06c0e689194a2fab306057", "observedAt": "2026-10-24T16:13:05+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23b", "name": "glossary-endnotes-ref-override-charset", "sha256": "5483e41dc53d58d9cd89a1fce55dd073841dc1800433f2fc0f9da9d8a29dfa08", "observedAt": "2026-10-24T16:12:58.385Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__glossary-endnotes-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__glossary-endnotes-ref-override-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s23b", "name": "glossary-endnotes-ref-override-exact-control", "sha256": "de68a75da0b11ec668b6a82816b7b62006be71e83252d70cd1f4fef923b60df7", "observedAt": "2026-10-24T16:13:05+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s23b", "name": "s23b-control-minimal-end", "sha256": "261061f455b57873fd15855488e7cb8b68dff00396809de74c7fffa5edda65a0", "observedAt": "2026-10-24T16:13:05+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 24: 18:10Z–18:12Z, validator columns at 70381216

The items adversarial review AX suspected at layer 127 (ledger on #599): SX1 (#600), SX2 (#601) and SX3 (#595), each with its exact-type control. The main-document stories are built as in session 20, the glossary footer as in session 23, the glossary styles part as in session 21, and the glossary theme as in session 20.

| Run    | Observed  | Specimen                                     | Issue        | Shape                                                                                                                                                                                                                                                                                | SHA-256 (first 16) | Word           | word-valid at 70381216                                                    | strict at 70381216                                                                                                             |
| ------ | --------- | -------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `s24a` | 18:12:11Z | `s24a-control-minimal`                       | control      | —                                                                                                                                                                                                                                                                                    | `a2612279d39ed5de` | clean-open     | valid                                                                     | valid                                                                                                                          |
| `s24a` | 18:11:17Z | `main-footer-typed-header-exact`             | #600         | `word/footer9.xml` (`w:ftr`), which the main document references through `w:footerReference` in its body's `w:sectPr`; its `Override` carries the exact **header** type `…wordprocessingml.header+xml`                                                                               | `689c3d2c9d984d82` | repair-warning | valid                                                                     | invalid (`paraid-missing-element@word/footer9.xml`)                                                                            |
| `s24a` | 18:12:11Z | `main-footer-override-exact-control`         | #600 control | `word/footer9.xml` (`w:ftr`), which the main document references through `w:footerReference` in its body's `w:sectPr`; its `Override` carries the exact footer type                                                                                                                  | `2135dc5452c875c7` | clean-open     | valid                                                                     | invalid (`paraid-missing-element@word/footer9.xml`)                                                                            |
| `s24a` | 18:12:09Z | `main-header-typed-footer-exact`             | #600         | `word/header9.xml` (`w:hdr`), which the main document references through `w:headerReference` in its body's `w:sectPr`; its `Override` carries the exact **footer** type `…wordprocessingml.footer+xml`                                                                               | `e5842c96db04e1db` | repair-warning | valid                                                                     | invalid (`paraid-missing-element@word/header9.xml`)                                                                            |
| `s24a` | 18:12:11Z | `main-header-override-exact-control`         | #600 control | `word/header9.xml` (`w:hdr`), which the main document references through `w:headerReference` in its body's `w:sectPr`; its `Override` carries the exact header type                                                                                                                  | `92b70ccc7ad7f0b6` | clean-open     | valid                                                                     | invalid (`paraid-missing-element@word/header9.xml`)                                                                            |
| `s24a` | 18:10:54Z | `glossary-footer-typed-header-exact`         | #600         | `word/glossary/footer9.xml` (`w:ftr`), which a reached glossary references through `w:footerReference` in the `w:sectPr` ending its `docPartBody`, related by the glossary's own `.rels` (`footer`); its `Override` carries the exact **header** type `…wordprocessingml.header+xml` | `58c14cebff6ec84f` | repair-warning | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)              |
| `s24a` | 18:10:06Z | `glossary-footer-typed-header-charset`       | #600         | `word/glossary/footer9.xml` (`w:ftr`), which a reached glossary references through `w:footerReference` in the `w:sectPr` ending its `docPartBody`, related by the glossary's own `.rels` (`footer`); its `Override` carries the **header** type plus `; charset=utf-8`               | `187c20452110f681` | repair-warning | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)              |
| `s24a` | 18:12:11Z | `s24a-control-minimal-end`                   | control      | —                                                                                                                                                                                                                                                                                    | `a2612279d39ed5de` | clean-open     | valid                                                                     | valid                                                                                                                          |
| `s24b` | 18:12:54Z | `s24b-control-minimal`                       | control      | —                                                                                                                                                                                                                                                                                    | `9c778b7917f34faf` | clean-open     | valid                                                                     | valid                                                                                                                          |
| `s24b` | 18:12:54Z | `glossary-footer-ref-override-exact-control` | #600 control | `word/glossary/footer9.xml` (`w:ftr`), which a reached glossary references through `w:footerReference` in the `w:sectPr` ending its `docPartBody`, related by the glossary's own `.rels` (`footer`); its `Override` carries the exact footer type                                    | `7a8a0005c4da6feb` | clean-open     | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`, `paraid-missing-element@word/glossary/footer9.xml`)              |
| `s24b` | 18:12:47Z | `glossary-styles-default-generic`            | #601         | a reached glossary that references no story, whose own `.rels` relates `word/glossary/styles.xml` (`styles`, an empty `w:styles`) and has no `Override`, so the generic `Default Extension="xml" ContentType="application/xml"` types it                                             | `062d0f1277455e61` | repair-warning | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                  |
| `s24b` | 18:12:54Z | `glossary-styles-override-exact-control`     | #601 control | a reached glossary that references no story, whose own `.rels` relates `word/glossary/styles.xml` (`styles`, an empty `w:styles`) with an `Override` carrying the exact styles type                                                                                                  | `a0cbe1f1f3c4c69e` | clean-open     | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                  |
| `s24b` | 18:12:52Z | `glossary-theme-override-text-xml`           | #595         | a reached glossary that references no story, whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`, session 20's well-formed theme); its `Override` carries `text/xml`                                                                                                 | `a5f8ddaf845b7dfd` | repair-warning | invalid (`word-part-content-type-generic@word/glossary/theme/theme1.xml`) | invalid (`word-part-content-type-generic@word/glossary/theme/theme1.xml`, `paraid-missing-element@word/glossary/document.xml`) |
| `s24b` | 18:12:54Z | `glossary-theme-override-exact-control`      | #595 control | a reached glossary that references no story, whose own `.rels` relates `word/glossary/theme/theme1.xml` (`theme`, session 20's well-formed theme); its `Override` carries the exact theme type                                                                                       | `4a057eda6658bd2b` | clean-open     | valid                                                                     | invalid (`paraid-missing-element@word/glossary/document.xml`)                                                                  |
| `s24b` | 18:12:54Z | `s24b-control-minimal-end`                   | control      | —                                                                                                                                                                                                                                                                                    | `9c778b7917f34faf` | clean-open     | valid                                                                     | valid                                                                                                                          |

Each chunk's two minimal controls are byte-identical; the chunks' controls differ only in ZIP entry timestamps.

<details><summary>Raw records, session 24</summary>

```jsonl
{"run": "s24a", "name": "s24a-control-minimal", "sha256": "a2612279d39ed5de91eda606ffab991756a2263106d6cf8ba306b35139a96589", "observedAt": "2026-10-24T18:12:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24a", "name": "main-footer-typed-header-exact", "sha256": "689c3d2c9d984d8239d04b85e016e4b6437cc4d83b947314af52f9029d0f0452", "observedAt": "2026-10-24T18:11:17.421Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00003__wfv__main-footer-typed-header-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s24a", "name": "main-footer-override-exact-control", "sha256": "2135dc5452c875c7179a45ad5c0eb3245e42e20b998389d7a233064ba16fcdbf", "observedAt": "2026-10-24T18:12:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24a", "name": "main-header-typed-footer-exact", "sha256": "e5842c96db04e1dbc92077ceba474be3b0fc2d58d68c4816c0e7bc826a02779e", "observedAt": "2026-10-24T18:12:09.639Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__main-header-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__main-header-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s24a", "name": "main-header-override-exact-control", "sha256": "92b70ccc7ad7f0b68d80ad374a8c3d66bbfbfc8248fbe425159f0c6d013043da", "observedAt": "2026-10-24T18:12:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24a", "name": "glossary-footer-typed-header-exact", "sha256": "58c14cebff6ec84f1fd11f7820b4318e3a93f30ca333c20579dcf70476133878", "observedAt": "2026-10-24T18:10:54.529Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__glossary-footer-typed-header-exact.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__glossary-footer-typed-header-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__glossary-footer-typed-header-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s24a", "name": "glossary-footer-typed-header-charset", "sha256": "187c20452110f68157d70f5ec703191ccead4c09669c736bf5bb9e84a08c02b2", "observedAt": "2026-10-24T18:10:06.481Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__glossary-footer-typed-header-charset.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00000__wfv__glossary-footer-typed-header-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s24a", "name": "s24a-control-minimal-end", "sha256": "a2612279d39ed5de91eda606ffab991756a2263106d6cf8ba306b35139a96589", "observedAt": "2026-10-24T18:12:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24b", "name": "s24b-control-minimal", "sha256": "9c778b7917f34fafae13ce6916305dc7a008ef89161a96e1a2f0e79098777669", "observedAt": "2026-10-24T18:12:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24b", "name": "glossary-footer-ref-override-exact-control", "sha256": "7a8a0005c4da6feb1e18e683f7063e6a25ec127d001401e101c54cb94cce6025", "observedAt": "2026-10-24T18:12:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24b", "name": "glossary-styles-default-generic", "sha256": "062d0f1277455e617cb62d8c22624d4dc50ef7335a1dc554e8e8c25a7d28c869", "observedAt": "2026-10-24T18:12:47.875Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__glossary-styles-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__glossary-styles-default-generic.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s24b", "name": "glossary-styles-override-exact-control", "sha256": "a0cbe1f1f3c4c69e5c7aec19b6765602ebb6cd0586cd34a04b76cb0afeb241c9", "observedAt": "2026-10-24T18:12:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24b", "name": "glossary-theme-override-text-xml", "sha256": "a5f8ddaf845b7dfdf1befc631b9fbea3e85f375b1ef9bb1dbc42a322f69ea723", "observedAt": "2026-10-24T18:12:52.086Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-theme-override-text-xml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-theme-override-text-xml.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s24b", "name": "glossary-theme-override-exact-control", "sha256": "4a057eda6658bd2bd27f80d054a09bcb994fec20fc2f0999a0150e394937bbb9", "observedAt": "2026-10-24T18:12:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s24b", "name": "s24b-control-minimal-end", "sha256": "9c778b7917f34fafae13ce6916305dc7a008ef89161a96e1a2f0e79098777669", "observedAt": "2026-10-24T18:12:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 25: 18:37Z, validator columns at 4f1372c5

The fixtures whose profile-less verdict the Validator Diff Report on #322 flagged as drift. The two eigen fixtures had no Word observation (`unknown` in `tests/fixtures-all.manifest.json`); the broken one, pinned clean-open, is the control. The validator columns hold the same verdicts at the base 9aaeeeae.

| Run    | Observed  | Specimen                                     | Issue        | Shape                                                                                                                        | SHA-256 (first 16) | Word       | word-valid at 4f1372c5 | strict at 4f1372c5                                                                |
| ------ | --------- | -------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | ------------------ | ---------- | ---------------------- | --------------------------------------------------------------------------------- |
| `s25a` | 18:37:54Z | `s25a-1-eigen-blue-bold-centered`            | #322 drift   | `tests/fixtures/eigen/blue-bold-centered-demo.id-paraid-overflow.docx`, unchanged                                            | `491a25750702125a` | clean-open | valid                  | invalid: `id-paraid-overflow`, `style-default-missing`, `textid-missing-element`  |
| `s25a` | 18:37:54Z | `s25a-2-eigen-line-spacing`                  | #322 drift   | `tests/fixtures/eigen/1-5-line-spacing.id-paraid-overflow.docx`, unchanged                                                   | `70bed70face08508` | clean-open | valid                  | invalid: `id-paraid-overflow`, `style-default-missing`, `textid-missing-element`  |
| `s25a` | 18:37:54Z | `s25a-3-control-broken-footnotes-dup-paraid` | #322 control | `tests/fixtures/broken/footnotes.duplicate-paraid.docx`, unchanged (pinned clean-open in `tests/fixtures-all.manifest.json`) | `64bdd3aded1a507a` | clean-open | valid                  | invalid: `id-paraid-overflow`, `paraid-missing-element`, `textid-missing-element` |

<details><summary>Raw records, session 25</summary>

```jsonl
{"run": "s25a", "name": "s25a-1-eigen-blue-bold-centered", "sha256": "491a25750702125a22197bdcd5a83047da989d7b790d2443e9f115a5298655f6", "observedAt": "2026-10-24T18:37:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s25a", "name": "s25a-2-eigen-line-spacing", "sha256": "70bed70face08508b06953c9c238fe37236354b80c23d72f5d49987365cd71be", "observedAt": "2026-10-24T18:37:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s25a", "name": "s25a-3-control-broken-footnotes-dup-paraid", "sha256": "64bdd3aded1a507a71d55aa79f2591310832d3557faafb9b569d1ad173255d85", "observedAt": "2026-10-24T18:37:54+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 26: 19:15Z, 20:54Z and 21:01Z, validator columns at af20d641

The shapes adversarial review AY of #602 suspected (S-A, S-B) and the glossary header its finding F3 says session 24 never ran. `s26b` isolates S-A after `s26a` showed every `w:headerReference` through a footer relationship refused; `s26c` probes the shapes #606 left open. af20d641 and its re-parented copy 697f9405 have the same tree.

| Run    | Observed  | Specimen                                         | Issue        | Shape                                                                                                                                     | SHA-256 (first 16) | Word           | word-valid at af20d641                     | strict at af20d641                                                                       |
| ------ | --------- | ------------------------------------------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------- |
| `s26a` | 19:19:19Z | `s26a-control-minimal`                           | control      | `MINIMAL_PARTS`                                                                                                                           | `74e942d9e276512e` | clean-open     | valid                                      | valid                                                                                    |
| `s26a` | 19:18:28Z | `headerref-footer-rel-typed-footer-exact`        | #606         | body `w:headerReference` → footer relationship → `w:hdr` part, typed `footer+xml`                                                         | `ad88d9fb907fb2a7` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`                                    |
| `s26a` | 19:17:39Z | `headerref-footer-rel-typed-footer-charset`      | #606         | the same, typed `footer+xml; charset=utf-8`                                                                                               | `8f48f8951350d6ff` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`, `word-part-content-type-inexact`  |
| `s26a` | 19:19:17Z | `headerref-footer-rel-typed-header-exact`        | #606         | the same, typed `header+xml`                                                                                                              | `74288497762a4e8b` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`, `word-part-content-type-mismatch` |
| `s26a` | 19:15:56Z | `footer-read-unused-header-rel-typed-header`     | #607         | body `w:footerReference` → footer relationship → `w:ftr` part, which an unreferenced header relationship also targets, typed `header+xml` | `266e0d3ef8b10063` | repair-warning | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26a` | 19:19:19Z | `footer-read-unused-header-rel-typed-footer`     | #607 control | the same, typed `footer+xml`                                                                                                              | `51dc05ced962318f` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26a` | 19:16:48Z | `glossary-header-typed-footer-exact`             | #610         | a reached glossary's `w:docPartBody` `w:sectPr` `w:headerReference` → header relationship → `w:hdr` part, typed `footer+xml`              | `72d8ea23105b9b55` | repair-warning | invalid: `word-part-content-type-mismatch` | invalid: `paraid-missing-element`, `word-part-content-type-mismatch`                     |
| `s26a` | 19:19:19Z | `s26a-control-minimal-end`                       | control      | `MINIMAL_PARTS`                                                                                                                           | `74e942d9e276512e` | clean-open     | valid                                      | valid                                                                                    |
| `s26b` | 20:55:30Z | `s26b-control-minimal`                           | control      | `MINIMAL_PARTS`                                                                                                                           | `b00d699b9917b644` | clean-open     | valid                                      | valid                                                                                    |
| `s26b` | 20:55:30Z | `headerref-header-rel-hdr-typed-header`          | #606 control | body `w:headerReference` → header relationship → `w:hdr` part, typed `header+xml`                                                         | `cc35191a6e3962f0` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26b` | 20:54:34Z | `headerref-footer-rel-ftr-typed-footer`          | #606         | body `w:headerReference` → footer relationship → `w:ftr` part, typed `footer+xml`                                                         | `07627be2f4abc499` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`                                    |
| `s26b` | 20:55:30Z | `footerref-footer-rel-hdr-typed-footer`          | #606 control | body `w:footerReference` → footer relationship → `w:hdr` part, typed `footer+xml`                                                         | `057656e77a3123dd` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26b` | 20:55:30Z | `headerref-header-rel-ftr-typed-header`          | #606 control | body `w:headerReference` → header relationship → `w:ftr` part, typed `header+xml`                                                         | `b2d7f02e99a8f0b5` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26b` | 20:55:27Z | `headerref-footer-rel-hdr-typed-styles`          | #606         | body `w:headerReference` → footer relationship → `w:hdr` part, typed `styles+xml`                                                         | `ce63cb6fc4a34403` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`, `word-part-content-type-mismatch` |
| `s26b` | 20:55:30Z | `s26b-control-minimal-end`                       | control      | `MINIMAL_PARTS`                                                                                                                           | `b00d699b9917b644` | clean-open     | valid                                      | valid                                                                                    |
| `s26c` | 21:02:53Z | `s26c-control-minimal`                           | control      | `MINIMAL_PARTS`                                                                                                                           | `078366e639a13560` | clean-open     | valid                                      | valid                                                                                    |
| `s26c` | 21:02:33Z | `footerref-header-rel-hdr-typed-header`          | #606         | body `w:footerReference` → header relationship → `w:hdr` part, typed `header+xml`                                                         | `dd1ea45a5e504eb9` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`                                    |
| `s26c` | 21:02:26Z | `footerref-header-rel-ftr-typed-footer`          | #606         | body `w:footerReference` → header relationship → `w:ftr` part, typed `footer+xml`                                                         | `de506dada5751c0f` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`, `word-part-content-type-mismatch` |
| `s26c` | 21:02:47Z | `glossary-headerref-footer-rel-ftr-typed-footer` | #606         | glossary `w:headerReference` → footer relationship → `w:ftr` part, typed `footer+xml`                                                     | `7796d049d97df892` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`                                    |
| `s26c` | 21:02:37Z | `glossary-footerref-header-rel-hdr-typed-header` | #606         | glossary `w:footerReference` → header relationship → `w:hdr` part, typed `header+xml`                                                     | `e356d53c331df5f6` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-mismatch`                                    |
| `s26c` | 21:02:53Z | `glossary-footerref-footer-rel-ftr-typed-footer` | #606 control | glossary `w:footerReference` → footer relationship → `w:ftr` part, typed `footer+xml`                                                     | `a04de026ef8ff770` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                        |
| `s26c` | 21:02:51Z | `headerref-styles-rel`                           | #606         | body `w:headerReference` naming `MINIMAL_PARTS`' styles relationship `rId1`                                                               | `190d0251b66682b4` | repair-warning | valid                                      | invalid: `rels-id-mismatch`                                                              |
| `s26c` | 21:02:53Z | `s26c-control-minimal-end`                       | control      | `MINIMAL_PARTS`                                                                                                                           | `078366e639a13560` | clean-open     | valid                                      | valid                                                                                    |

<details><summary>Raw records, session 26</summary>

```jsonl
{"run": "s26a", "name": "s26a-control-minimal", "sha256": "74e942d9e276512e1e829f0baab80800769af83e931bc25f775365fa19026e84", "observedAt": "2026-10-24T19:19:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26a", "name": "headerref-footer-rel-typed-footer-exact", "sha256": "ad88d9fb907fb2a7d6684e83c4b3467615c3570d8b0211aa9b9ec6066756a016", "observedAt": "2026-10-24T19:18:28.377Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__headerref-footer-rel-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__headerref-footer-rel-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26a", "name": "headerref-footer-rel-typed-footer-charset", "sha256": "8f48f8951350d6ff5ff374b36135f1bb22f3dcdc8413a9c7ba0281d88488a557", "observedAt": "2026-10-24T19:17:39.863Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00003__wfv__headerref-footer-rel-typed-footer-charset.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s26a", "name": "headerref-footer-rel-typed-header-exact", "sha256": "74288497762a4e8bde336d170c32fb44447a51484f8bf0734a25cf9158a54dcb", "observedAt": "2026-10-24T19:19:17.925Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__headerref-footer-rel-typed-header-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__headerref-footer-rel-typed-header-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26a", "name": "footer-read-unused-header-rel-typed-header", "sha256": "266e0d3ef8b100632da8eeccc0ef761d3c3fe623dd78653250f57007285a48b0", "observedAt": "2026-10-24T19:15:56.709Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__footer-read-unused-header-rel-typed-header.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00001__wfv__footer-read-unused-header-rel-typed-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s26a", "name": "footer-read-unused-header-rel-typed-footer", "sha256": "51dc05ced962318fb788849065aee65ca755bbdf5aee9d3a5317f902a286a913", "observedAt": "2026-10-24T19:19:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26a", "name": "glossary-header-typed-footer-exact", "sha256": "72d8ea23105b9b55e32dff7b5b6d67a31910d778b9b46fdd4a20c1be2815ad69", "observedAt": "2026-10-24T19:16:48.261Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__glossary-header-typed-footer-exact.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__glossary-header-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__glossary-header-typed-footer-exact.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26a", "name": "s26a-control-minimal-end", "sha256": "74e942d9e276512e1e829f0baab80800769af83e931bc25f775365fa19026e84", "observedAt": "2026-10-24T19:19:19+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26b", "name": "s26b-control-minimal", "sha256": "b00d699b9917b6447d83dea6e64f81dcdc6346784ec9d2a5f83e8319f111861f", "observedAt": "2026-10-24T20:55:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26b", "name": "headerref-header-rel-hdr-typed-header", "sha256": "cc35191a6e3962f0c9947973761298079dc52e5801810184744dcaa1aa957c22", "observedAt": "2026-10-24T20:55:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26b", "name": "headerref-footer-rel-ftr-typed-footer", "sha256": "07627be2f4abc499683ddb53cd2bf770b6ae82cd5f27960652243ee206c4bb5f", "observedAt": "2026-10-24T20:54:34.839Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__headerref-footer-rel-ftr-typed-footer.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00001__wfv__headerref-footer-rel-ftr-typed-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s26b", "name": "footerref-footer-rel-hdr-typed-footer", "sha256": "057656e77a3123ddf0c15264e683d6000c88a8530bda09ce0f6c839af1ee700a", "observedAt": "2026-10-24T20:55:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26b", "name": "headerref-header-rel-ftr-typed-header", "sha256": "b2d7f02e99a8f0b5a528a888a8c9c87836011b3143614261ac32a31907fd5235", "observedAt": "2026-10-24T20:55:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26b", "name": "headerref-footer-rel-hdr-typed-styles", "sha256": "ce63cb6fc4a344038c441f67cdbce7131624efd33ad99cca3525c3c2418b6401", "observedAt": "2026-10-24T20:55:27.694Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00002__wfv__headerref-footer-rel-hdr-typed-styles.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s26b", "name": "s26b-control-minimal-end", "sha256": "b00d699b9917b6447d83dea6e64f81dcdc6346784ec9d2a5f83e8319f111861f", "observedAt": "2026-10-24T20:55:30+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26c", "name": "s26c-control-minimal", "sha256": "078366e639a135606430fccdb4b2089242ca43724ca68e2ee2ddc340b8b4aab2", "observedAt": "2026-10-24T21:02:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26c", "name": "footerref-header-rel-hdr-typed-header", "sha256": "dd1ea45a5e504eb9b24c7400d9db2e45ec929d674e91b592db133a79a660a4c2", "observedAt": "2026-10-24T21:02:33.018Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00001__wfv__footerref-header-rel-hdr-typed-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26c", "name": "footerref-header-rel-ftr-typed-footer", "sha256": "de506dada5751c0fa4414bdaa3945815a03c058d926c15f198532d8259b4ebae", "observedAt": "2026-10-24T21:02:26.880Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__footerref-header-rel-ftr-typed-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__footerref-header-rel-ftr-typed-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s26c", "name": "glossary-headerref-footer-rel-ftr-typed-footer", "sha256": "7796d049d97df89254be8f0bcc4ce7383cf84de33bf0f647adb732a81df2b7db", "observedAt": "2026-10-24T21:02:47.266Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__glossary-headerref-footer-rel-ftr-typed-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__glossary-headerref-footer-rel-ftr-typed-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26c", "name": "glossary-footerref-header-rel-hdr-typed-header", "sha256": "e356d53c331df5f6f128659348bad3d36ebd57758527290856ded442b870cb26", "observedAt": "2026-10-24T21:02:37.389Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__glossary-footerref-header-rel-hdr-typed-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__glossary-footerref-header-rel-hdr-typed-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26c", "name": "glossary-footerref-footer-rel-ftr-typed-footer", "sha256": "a04de026ef8ff7702858bc2267c971aa50c27c64b3d1818b7a2f2fa5f2d73a04", "observedAt": "2026-10-24T21:02:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s26c", "name": "headerref-styles-rel", "sha256": "190d0251b66682b41d3f2bdcea46583011a76c60cf19153d9e5dc1617cb1a671", "observedAt": "2026-10-24T21:02:51.554Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__headerref-styles-rel.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__headerref-styles-rel.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s26c", "name": "s26c-control-minimal-end", "sha256": "078366e639a135606430fccdb4b2089242ca43724ca68e2ee2ddc340b8b4aab2", "observedAt": "2026-10-24T21:02:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 27: 22:11Z–22:14Z, validator columns at 9eb10acb

The relationship Types, duplicate Ids and placements adversarial review AZ of #611 suspected (S1–S3), and the placements layer 129's check judges without a session 26 observation. `s27c` repeats on the footer side the URI results of `s27a` and `s27b`.

| Run    | Observed  | Specimen                                  | Issue             | Shape                                                                                                                                                 | SHA-256 (first 16) | Word           | word-valid at 9eb10acb                     | strict at 9eb10acb                                                                                                    |
| ------ | --------- | ----------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `s27a` | 22:12:17Z | `s27a-control-minimal`                    | control           | `MINIMAL_PARTS`                                                                                                                                       | `869e695282c0ac34` | clean-open     | valid                                      | valid                                                                                                                 |
| `s27a` | 22:12:06Z | `headerref-header-rel-type-padded`        | #613              | the clean session 26 shape (body `w:headerReference` → header relationship → `w:hdr` part, typed `header+xml`), Type padded with a space on each side | `e41055eb54be1bc8` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27a` | 22:12:10Z | `headerref-header-rel-type-tab-newline`   | #613              | the same, Type wrapped in `&#x9;` … `&#xA;`                                                                                                           | `06d301d30ccebff4` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27a` | 22:12:15Z | `headerref-header-rel-type-upper`         | #613              | the same, Type `…/relationships/HEADER`                                                                                                               | `625316b0531f4d31` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27a` | 22:12:02Z | `headerref-header-rel-type-example-com`   | #613              | the same, Type `http://example.com/header`                                                                                                            | `4ec88fbfeb764714` | repair-warning | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27a` | 22:11:58Z | `headerref-header-rel-type-custom-header` | #613              | the same, Type `…/relationships/custom/header`                                                                                                        | `45b7ce68b4ef8874` | repair-warning | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27a` | 22:11:53Z | `headerref-duplicate-id-last-footer`      | AZ S3             | the clean session 26 shape plus a second Relationship with its Id, Type footer, listed last                                                           | `d006527d1b64576d` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `rels-id-duplicate`, `word-header-footer-relationship`, `xsd-error`, `xsd-summary` |
| `s27a` | 22:12:17Z | `s27a-control-minimal-end`                | control           | `MINIMAL_PARTS`                                                                                                                                       | `869e695282c0ac34` | clean-open     | valid                                      | valid                                                                                                                 |
| `s27b` | 22:13:11Z | `s27b-control-minimal`                    | control           | `MINIMAL_PARTS`                                                                                                                                       | `7abfb1d3fe2e35cd` | clean-open     | valid                                      | valid                                                                                                                 |
| `s27b` | 22:12:56Z | `headerref-duplicate-id-last-header`      | AZ S3             | body `w:headerReference` → footer relationship → `w:ftr` part, typed `footer+xml`, plus a second Relationship with its Id, Type header, listed last   | `8501b69a53e7b536` | repair-warning | invalid: `word-part-content-type-mismatch` | invalid: `paraid-missing-element`, `rels-id-duplicate`, `word-part-content-type-mismatch`, `xsd-error`, `xsd-summary` |
| `s27b` | 22:13:04Z | `headerref-footer-rel-paragraph-sectpr`   | placement         | body `w:headerReference` → footer relationship → `w:ftr` part, the reference in a paragraph's `w:pPr/w:sectPr`                                        | `6c823d54915a0fdc` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27b` | 22:13:00Z | `headerref-footer-rel-in-sectprchange`    | placement         | the same reference in the `w:sectPr` of a `w:sectPrChange` (last child of the body `w:sectPr`)                                                        | `a4a142d57e2cd709` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`, `xsd-error`, `xsd-summary`                      |
| `s27b` | 22:13:11Z | `headerref-header-rel-in-sectprchange`    | placement control | the clean session 26 shape, the reference in the `w:sectPr` of a `w:sectPrChange`                                                                     | `cb5eeab3d602f7aa` | clean-open     | valid                                      | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                         |
| `s27b` | 22:13:08Z | `headerref-header-rel-type-bare`          | #613              | the clean session 26 shape, Type `header`                                                                                                             | `bd620b2afd27ce6e` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27b` | 22:13:11Z | `headerref-header-rel-type-strict-uri`    | #613 control      | the clean session 26 shape, Type `http://purl.oclc.org/ooxml/officeDocument/relationships/header`                                                     | `cad89fe4e31c3318` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27b` | 22:13:11Z | `s27b-control-minimal-end`                | control           | `MINIMAL_PARTS`                                                                                                                                       | `7abfb1d3fe2e35cd` | clean-open     | valid                                      | valid                                                                                                                 |
| `s27c` | 22:14:14Z | `s27c-control-minimal`                    | control           | `MINIMAL_PARTS`                                                                                                                                       | `247b8c451e5e9b85` | clean-open     | valid                                      | valid                                                                                                                 |
| `s27c` | 22:14:08Z | `footerref-footer-rel-type-example-com`   | #613              | body `w:footerReference` → footer relationship → `w:ftr` part, typed `footer+xml`, Type `http://example.com/footer`                                   | `a7f89c43b69aa6eb` | repair-warning | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27c` | 22:14:03Z | `footerref-footer-rel-type-custom-footer` | #613              | the same, Type `…/relationships/custom/footer`                                                                                                        | `51d8d414915e2626` | repair-warning | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27c` | 22:14:12Z | `footerref-footer-rel-type-upper`         | #613              | the same, Type `…/relationships/FOOTER`                                                                                                               | `2139a90eff15b632` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s27c` | 22:14:14Z | `footerref-footer-rel-type-strict-uri`    | #613 control      | the same, Type `http://purl.oclc.org/ooxml/officeDocument/relationships/footer`                                                                       | `f7f1b2166e9c0ed0` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27c` | 22:14:14Z | `footerref-footer-rel-ftr-typed-footer`   | #613 control      | the same, Type unchanged (Transitional)                                                                                                               | `1117edc61cf701f4` | clean-open     | valid                                      | invalid: `paraid-missing-element`                                                                                     |
| `s27c` | 22:14:14Z | `s27c-control-minimal-end`                | control           | `MINIMAL_PARTS`                                                                                                                                       | `df85a4aa94a79dbc` | clean-open     | valid                                      | valid                                                                                                                 |

<details><summary>Raw records, session 27</summary>

```jsonl
{"run": "s27a", "name": "s27a-control-minimal", "sha256": "869e695282c0ac349050743139f8f286e5112bbc9702e3f846f93b9da80e08e5", "observedAt": "2026-10-24T22:12:17+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27a", "name": "headerref-header-rel-type-padded", "sha256": "e41055eb54be1bc81b49bbdaa40b07f7a5018a59bd23750f621045536766e63a", "observedAt": "2026-10-24T22:12:06.617Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__headerref-header-rel-type-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__headerref-header-rel-type-padded.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "headerref-header-rel-type-tab-newline", "sha256": "06d301d30ccebff49015103e5a0379260f6df6b450e4a79e67bfcbdf8cbe5069", "observedAt": "2026-10-24T22:12:10.818Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__headerref-header-rel-type-tab-newline.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__headerref-header-rel-type-tab-newline.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "headerref-header-rel-type-upper", "sha256": "625316b0531f4d31dc24a1950d66783e46730ea1517d74925b261fbcec45a224", "observedAt": "2026-10-24T22:12:15.051Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__headerref-header-rel-type-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__headerref-header-rel-type-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "headerref-header-rel-type-example-com", "sha256": "4ec88fbfeb7647143d4f641e2027302c49dbcdf4fa0470c9fed8833ec909cf64", "observedAt": "2026-10-24T22:12:02.383Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__headerref-header-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__headerref-header-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "headerref-header-rel-type-custom-header", "sha256": "45b7ce68b4ef887497ad13c1f67ae7ae779a5a988b9855bfefc50f6632bf8361", "observedAt": "2026-10-24T22:11:58.158Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__headerref-header-rel-type-custom-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__headerref-header-rel-type-custom-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "headerref-duplicate-id-last-footer", "sha256": "d006527d1b64576dfbe75aed4bf820e3949849a8c47f2d7db41fb09a94625222", "observedAt": "2026-10-24T22:11:53.940Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__headerref-duplicate-id-last-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__headerref-duplicate-id-last-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27a", "name": "s27a-control-minimal-end", "sha256": "869e695282c0ac349050743139f8f286e5112bbc9702e3f846f93b9da80e08e5", "observedAt": "2026-10-24T22:12:17+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27b", "name": "s27b-control-minimal", "sha256": "7abfb1d3fe2e35cdb4e0f1118ee4bb472c2ad3523f184c8465bdb089711c62ac", "observedAt": "2026-10-24T22:13:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27b", "name": "headerref-duplicate-id-last-header", "sha256": "8501b69a53e7b536da079c3f5b1b1fe2b6da6450164eac3edf75e7dcde48dbe5", "observedAt": "2026-10-24T22:12:56.199Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__headerref-duplicate-id-last-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__headerref-duplicate-id-last-header.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27b", "name": "headerref-footer-rel-paragraph-sectpr", "sha256": "6c823d54915a0fdcc7c05cd4b8162b9b01270f9f4989f913c40b1f1fc92d73c8", "observedAt": "2026-10-24T22:13:04.626Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__headerref-footer-rel-paragraph-sectpr.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__headerref-footer-rel-paragraph-sectpr.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27b", "name": "headerref-footer-rel-in-sectprchange", "sha256": "a4a142d57e2cd709b15be7894c8de53d65ac753efdf4b9ce3229ce7a7908d6a7", "observedAt": "2026-10-24T22:13:00.423Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__headerref-footer-rel-in-sectprchange.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__headerref-footer-rel-in-sectprchange.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27b", "name": "headerref-header-rel-in-sectprchange", "sha256": "cb5eeab3d602f7aabc7f8c824f7ff93bbcf2d8a88d91429dc8048dcec93bc8c4", "observedAt": "2026-10-24T22:13:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27b", "name": "headerref-header-rel-type-bare", "sha256": "bd620b2afd27ce6e9c99bd3cb083c083cd1a5852bebfb4c1e02f63153a655498", "observedAt": "2026-10-24T22:13:08.815Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__headerref-header-rel-type-bare.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__headerref-header-rel-type-bare.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27b", "name": "headerref-header-rel-type-strict-uri", "sha256": "cad89fe4e31c33188e2feaa5658dc1826baa0f43e44683d1fcb2384483b01c00", "observedAt": "2026-10-24T22:13:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27b", "name": "s27b-control-minimal-end", "sha256": "7abfb1d3fe2e35cdb4e0f1118ee4bb472c2ad3523f184c8465bdb089711c62ac", "observedAt": "2026-10-24T22:13:11+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27c", "name": "s27c-control-minimal", "sha256": "247b8c451e5e9b85565cf5036c81edd8b71d2e1819c1c889c5a34747f1194c5d", "observedAt": "2026-10-24T22:14:14+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27c", "name": "footerref-footer-rel-type-example-com", "sha256": "a7f89c43b69aa6eb06452bfc07348bfb299c2cfec3172a6e5ba9cf8b956b2d14", "observedAt": "2026-10-24T22:14:08.025Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__footerref-footer-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__footerref-footer-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27c", "name": "footerref-footer-rel-type-custom-footer", "sha256": "51d8d414915e262683906b760e7705cc5d01fbc0d890414d151abea2e10ea2cf", "observedAt": "2026-10-24T22:14:03.812Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__footerref-footer-rel-type-custom-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__footerref-footer-rel-type-custom-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27c", "name": "footerref-footer-rel-type-upper", "sha256": "2139a90eff15b632ec6b14031c3a8212f20236ef2a48f32b182d83c8414e3130", "observedAt": "2026-10-24T22:14:12.593Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__footerref-footer-rel-type-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__footerref-footer-rel-type-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s27c", "name": "footerref-footer-rel-type-strict-uri", "sha256": "f7f1b2166e9c0ed098e45464ba4e8c7b7c916754cf3f72bcd07499875ed28ca9", "observedAt": "2026-10-24T22:14:14+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27c", "name": "footerref-footer-rel-ftr-typed-footer", "sha256": "1117edc61cf701f4d9f10d9ab003946433e3665179e7f2d1eff8cdef44c40816", "observedAt": "2026-10-24T22:14:14+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s27c", "name": "s27c-control-minimal-end", "sha256": "df85a4aa94a79dbc90c0055b29fcd0b09784214f4797722221e92c9c5d85978d", "observedAt": "2026-10-24T22:14:14+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 28: 22:25Z–22:28Z, validator columns at 9eb10acb

Whether Word reads a hyperlink's relationship Type exactly, as session 27 found it does for header and footer references (#614).

| Run    | Observed  | Specimen                              | Issue        | Shape                                                                                                                                  | SHA-256 (first 16) | Word           | word-valid at 9eb10acb                 | strict at 9eb10acb                     |
| ------ | --------- | ------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------------------------------- | -------------------------------------- |
| `s28a` | 22:27:27Z | `s28a-control-minimal`                | control      | `MINIMAL_PARTS`                                                                                                                        | `79625c5d0847832d` | clean-open     | valid                                  | valid                                  |
| `s28a` | 22:27:27Z | `hyperlink-rel-type-transitional`     | #614 control | `MINIMAL_PARTS` plus a body `w:hyperlink r:id="rIdH"` → External relationship to `https://example.org/`, Type unchanged (Transitional) | `660a32ca683f9b8f` | clean-open     | valid                                  | valid                                  |
| `s28a` | 22:27:27Z | `hyperlink-rel-type-strict-uri`       | #614 control | the same, Type `http://purl.oclc.org/ooxml/officeDocument/relationships/hyperlink`                                                     | `c6b42a909bcfda00` | clean-open     | valid                                  | valid                                  |
| `s28a` | 22:26:38Z | `hyperlink-rel-type-example-com`      | #614         | the same, Type `http://example.com/hyperlink`                                                                                          | `72403616105b52b2` | repair-warning | valid                                  | valid                                  |
| `s28a` | 22:25:40Z | `hyperlink-rel-type-custom-hyperlink` | #614         | the same, Type `…/relationships/custom/hyperlink`                                                                                      | `96829b01ea8a331e` | repair-warning | valid                                  | valid                                  |
| `s28a` | 22:26:49Z | `hyperlink-rel-type-upper`            | #614         | the same, Type `…/relationships/HYPERLINK`                                                                                             | `b555e1aca1415647` | repair-warning | invalid: `word-hyperlink-relationship` | invalid: `word-hyperlink-relationship` |
| `s28a` | 22:27:27Z | `s28a-control-minimal-end`            | control      | `MINIMAL_PARTS`                                                                                                                        | `79625c5d0847832d` | clean-open     | valid                                  | valid                                  |

<details><summary>Raw records, session 28</summary>

```jsonl
{"run": "s28a", "name": "s28a-control-minimal", "sha256": "79625c5d0847832dc083e20bedcfaac2b054c8e0ac28145797a2735e66af2ee5", "observedAt": "2026-10-24T22:27:27+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s28a", "name": "hyperlink-rel-type-transitional", "sha256": "660a32ca683f9b8f976bd26015581a1783b8a75d3ad1629557b7767876ca631d", "observedAt": "2026-10-24T22:27:27+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s28a", "name": "hyperlink-rel-type-strict-uri", "sha256": "c6b42a909bcfda0014871b38fc8e3b0d22027efe5e2e05b982073458e40749d6", "observedAt": "2026-10-24T22:27:27+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s28a", "name": "hyperlink-rel-type-example-com", "sha256": "72403616105b52b2d454770c5cb867ce0cf06df2eeb573ebd9572d80bf422c93", "observedAt": "2026-10-24T22:26:38.165Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__hyperlink-rel-type-example-com.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__hyperlink-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__hyperlink-rel-type-example-com.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s28a", "name": "hyperlink-rel-type-custom-hyperlink", "sha256": "96829b01ea8a331e75dfb30e446105b57c35d4e2c5261760b8e4494836ff2691", "observedAt": "2026-10-24T22:25:40.247Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__hyperlink-rel-type-custom-hyperlink.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00000__wfv__hyperlink-rel-type-custom-hyperlink.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s28a", "name": "hyperlink-rel-type-upper", "sha256": "b555e1aca141564743e018977c057a55c7102a0aa7a24fa186845661776bb80f", "observedAt": "2026-10-24T22:26:49.547Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00004__wfv__hyperlink-rel-type-upper.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s28a", "name": "s28a-control-minimal-end", "sha256": "79625c5d0847832dc083e20bedcfaac2b054c8e0ac28145797a2735e66af2ee5", "observedAt": "2026-10-24T22:27:27+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 29: 22:57Z–23:05Z, validator columns at 4a5926d3

Duplicate relationship Ids without session 27's content-type confound (CodeRabbit's comment 4368831374 on #611, #615), and adversarial review BA's suspected `https:` Types (S1).

| Run    | Observed  | Specimen                                          | Issue        | Shape                                                                                                                                                                                                                                                                                         | SHA-256 (first 16) | Word           | word-valid at 4a5926d3                     | strict at 4a5926d3                                                                                                    |
| ------ | --------- | ------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `s29a` | 23:00:01Z | `s29a-control-minimal`                            | control      | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                               | `c88a5c2fa28c6fef` | clean-open     | valid                                      | valid                                                                                                                 |
| `s29a` | 22:58:03Z | `headerref-dup-id-footer-first-header-last`       | #615         | the clean session 26 shape (body `w:headerReference` `rIdX` → header relationship → `header9.xml`, a `w:hdr` typed `header+xml`) plus a `footer9.xml` (`w:ftr`, typed `footer+xml`); `document.xml.rels` lists `rIdX` → footer (`footer9.xml`) first and `rIdX` → header (`header9.xml`) last | `66450bf9b2ad6ae8` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-duplicate`, `xsd-error`, `xsd-summary`                                    |
| `s29a` | 22:59:04Z | `headerref-dup-id-header-first-footer-last`       | #615         | the same, header first and footer last                                                                                                                                                                                                                                                        | `a496f8130d77f2b5` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `rels-id-duplicate`, `word-header-footer-relationship`, `xsd-error`, `xsd-summary` |
| `s29a` | 22:59:58Z | `headerref-dup-id-header-twice`                   | #615         | the same, `rIdX` → header (`header9.xml`) twice                                                                                                                                                                                                                                               | `b6134671593da6ff` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-duplicate`, `rels-unreferenced`, `xsd-error`, `xsd-summary`               |
| `s29a` | 22:57:10Z | `dup-id-unreferenced-hyperlinks`                  | #615         | the same with one `rIdX` → header, plus two unreferenced External hyperlink relationships sharing `rIdZ`                                                                                                                                                                                      | `200dfe224785da37` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `rels-id-duplicate`, `rels-unreferenced`, `xsd-error`, `xsd-summary`               |
| `s29a` | 23:00:01Z | `headerref-header-rel-with-footer-part`           | control      | the same with one `rIdX` → header and nothing else                                                                                                                                                                                                                                            | `70094b63b06ebbfa` | clean-open     | valid                                      | invalid: `paraid-missing-element`, `rels-unreferenced`                                                                |
| `s29a` | 23:00:01Z | `s29a-control-minimal-end`                        | control      | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                               | `c88a5c2fa28c6fef` | clean-open     | valid                                      | valid                                                                                                                 |
| `s29b` | 23:04:23Z | `s29b-control-minimal`                            | control      | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                               | `2dbc2f882a291f2d` | clean-open     | valid                                      | valid                                                                                                                 |
| `s29b` | 23:03:25Z | `headerref-header-rel-type-https`                 | review BA S1 | the clean session 26 shape, Type `https://schemas.openxmlformats.org/officeDocument/2006/relationships/header`                                                                                                                                                                                | `701c0cae94f2045c` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s29b` | 23:02:23Z | `footerref-footer-rel-type-https`                 | review BA S1 | the clean footer shape (`w:footerReference` → footer relationship → `w:ftr` typed `footer+xml`), Type `https://…/footer`                                                                                                                                                                      | `4b8c16ddd86b56eb` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `paraid-missing-element`, `word-header-footer-relationship`                                                  |
| `s29b` | 23:03:35Z | `hyperlink-rel-type-https`                        | review BA S1 | session 28's hyperlink shape, Type `https://…/hyperlink`                                                                                                                                                                                                                                      | `a9ccebe9434410ed` | repair-warning | invalid: `word-hyperlink-relationship`     | invalid: `word-hyperlink-relationship`                                                                                |
| `s29b` | 23:01:29Z | `dup-id-package-rels-unreferenced-hyperlinks`     | #615         | the clean session 26 shape plus two unreferenced External hyperlink relationships sharing `rIdZ` in `_rels/.rels`                                                                                                                                                                             | `85e22167da2e4eb8` | repair-warning | valid                                      | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                         |
| `s29b` | 23:04:23Z | `dup-id-header-part-rels-unreferenced-hyperlinks` | #615         | the clean session 26 shape plus `word/_rels/header9.xml.rels` holding two unreferenced External hyperlink relationships sharing `rIdZ`                                                                                                                                                        | `fcf47cd10f419818` | clean-open     | valid                                      | invalid: `paraid-missing-element`, `rels-id-duplicate`, `xsd-error`, `xsd-summary`                                    |
| `s29b` | 23:04:23Z | `s29b-control-minimal-end`                        | control      | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                               | `2dbc2f882a291f2d` | clean-open     | valid                                      | valid                                                                                                                 |

<details><summary>Raw records, session 29</summary>

```jsonl
{"run": "s29a", "name": "s29a-control-minimal", "sha256": "c88a5c2fa28c6fef4c6a97ddea1ad0e186ef7bae0aaa96163f8f1d11b924542f", "observedAt": "2026-10-24T23:00:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s29a", "name": "headerref-dup-id-footer-first-header-last", "sha256": "66450bf9b2ad6ae893fb1b503615422495c76904f25e2914910e3fe9e1acec18", "observedAt": "2026-10-24T22:58:03.631Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__headerref-dup-id-footer-first-header-last.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__headerref-dup-id-footer-first-header-last.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__headerref-dup-id-footer-first-header-last.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29a", "name": "headerref-dup-id-header-first-footer-last", "sha256": "a496f8130d77f2b59e30844bc7dd57d32bdb2b429484a43760dea9b01b859200", "observedAt": "2026-10-24T22:59:04.084Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__headerref-dup-id-header-first-footer-last.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00002__wfv__headerref-dup-id-header-first-footer-last.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s29a", "name": "headerref-dup-id-header-twice", "sha256": "b6134671593da6ff59f42c013870aac52f808e6c747b5d5e418a36025cd157c3", "observedAt": "2026-10-24T22:59:58.265Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__headerref-dup-id-header-twice.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00003__wfv__headerref-dup-id-header-twice.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__headerref-dup-id-header-twice.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29a", "name": "dup-id-unreferenced-hyperlinks", "sha256": "200dfe224785da37b01fbc70d9553c1af40fbf03f8696794aba0683862152f0b", "observedAt": "2026-10-24T22:57:10.435Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__dup-id-unreferenced-hyperlinks.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__dup-id-unreferenced-hyperlinks.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__dup-id-unreferenced-hyperlinks.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29a", "name": "headerref-header-rel-with-footer-part", "sha256": "70094b63b06ebbfa0e073975ff0318a27eadd4aba82c722d54ad0470b90fe8ac", "observedAt": "2026-10-24T23:00:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s29a", "name": "s29a-control-minimal-end", "sha256": "c88a5c2fa28c6fef4c6a97ddea1ad0e186ef7bae0aaa96163f8f1d11b924542f", "observedAt": "2026-10-24T23:00:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s29b", "name": "s29b-control-minimal", "sha256": "2dbc2f882a291f2df9267ce3deebfa24f3e62a3f2b6e9959abfef65ac636a98d", "observedAt": "2026-10-24T23:04:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s29b", "name": "headerref-header-rel-type-https", "sha256": "701c0cae94f2045cb084b1fed30d12d781e1b859d8153139c42c9f9b3ff42e79", "observedAt": "2026-10-24T23:03:25.056Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__headerref-header-rel-type-https.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00003__wfv__headerref-header-rel-type-https.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__headerref-header-rel-type-https.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s29b", "name": "footerref-footer-rel-type-https", "sha256": "4b8c16ddd86b56eb5aa77aeacc62e3a48363259cc248283e050d1319795ad6ef", "observedAt": "2026-10-24T23:02:23.793Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__footerref-footer-rel-type-https.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__footerref-footer-rel-type-https.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__footerref-footer-rel-type-https.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29b", "name": "hyperlink-rel-type-https", "sha256": "a9ccebe9434410edac0046eb257c58f661bb31d5658b384fcff8c3c6e2203cfc", "observedAt": "2026-10-24T23:03:35.777Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00004__wfv__hyperlink-rel-type-https.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29b", "name": "dup-id-package-rels-unreferenced-hyperlinks", "sha256": "85e22167da2e4eb88ca32e6e3f8629baa8f4e4862af2fe4708d0d55157a8da23", "observedAt": "2026-10-24T23:01:29.727Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__dup-id-package-rels-unreferenced-hyperlinks.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__dup-id-package-rels-unreferenced-hyperlinks.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__dup-id-package-rels-unreferenced-hyperlinks.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s29b", "name": "dup-id-header-part-rels-unreferenced-hyperlinks", "sha256": "fcf47cd10f419818fab322c3ad2ff5694927ed2bf8085c780fb162e9a0c0a7d4", "observedAt": "2026-10-24T23:04:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s29b", "name": "s29b-control-minimal-end", "sha256": "2dbc2f882a291f2df9267ce3deebfa24f3e62a3f2b6e9959abfef65ac636a98d", "observedAt": "2026-10-24T23:04:23+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 30: 23:53Z–23:54Z, validator columns at 77d01c46

Adversarial review BB's suspected items on #615: a duplicate relationship Id in a reached glossary's `.rels` (S1, #617) and in the `.rels` of a document Word does not reach (S2), and the moved main document #615 resolves.

| Run    | Observed  | Specimen                                         | Issue               | Shape                                                                                                                                                                                                              | SHA-256 (first 16) | Word           | word-valid at 77d01c46       | strict at 77d01c46                                                                                  |
| ------ | --------- | ------------------------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------------- | ---------------------------- | --------------------------------------------------------------------------------------------------- |
| `s30a` | 23:54:31Z | `s30a-control-minimal`                           | control             | `MINIMAL_PARTS`                                                                                                                                                                                                    | `4220be34a673ce8b` | clean-open     | valid                        | valid                                                                                               |
| `s30a` | 23:54:31Z | `glossary-footerref-footer-rel-ftr-typed-footer` | control             | session 26's clean glossary footer shape (a glossary `w:footerReference` `rIdF` → footer relationship → `word/glossary/footer9.xml`, a `w:ftr` typed `footer+xml`)                                                 | `01abfee9a5282750` | clean-open     | valid                        | invalid: `paraid-missing-element`                                                                   |
| `s30a` | 23:53:53Z | `dup-id-glossary-sidecar`                        | #617 (review BB S1) | the same plus two unreferenced External hyperlink relationships sharing `rIdZ` in `word/glossary/_rels/document.xml.rels`                                                                                          | `f10d8c7646699480` | repair-warning | valid                        | invalid: `paraid-missing-element`, `rels-id-duplicate`, `xsd-error`, `xsd-summary`                  |
| `s30a` | 23:54:31Z | `relocated-main-transitional`                    | control             | `MINIMAL_PARTS` with the main document moved to `word/main.xml` (package relationship and Override retargeted)                                                                                                     | `231e9873ec77f2b5` | clean-open     | valid                        | valid                                                                                               |
| `s30a` | 23:54:31Z | `relocated-main-orphan-sidecar`                  | control             | the same plus an unreached `word/document.xml` and `word/_rels/document.xml.rels` (copies of the originals)                                                                                                        | `7ffd994eaebdc175` | clean-open     | valid                        | invalid: `ct-undeclared-part`, `rels-unreferenced`                                                  |
| `s30a` | 23:54:31Z | `dup-id-non-main-document-sidecar`               | review BB S2        | the same plus two unreferenced External hyperlink relationships sharing `rIdZ` in the orphan `word/_rels/document.xml.rels`                                                                                        | `7c240516e15e401b` | clean-open     | valid                        | invalid: `ct-undeclared-part`, `rels-id-duplicate`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s30a` | 23:54:18Z | `dup-id-relocated-main-transitional`             | #615                | `MINIMAL_PARTS` with the main document moved to `word/main.xml` (package relationship and Override retargeted) plus two unreferenced External hyperlink relationships sharing `rIdZ` in `word/_rels/main.xml.rels` | `cf7b780037c2c6b5` | repair-warning | invalid: `rels-id-duplicate` | invalid: `rels-id-duplicate`, `xsd-error`, `xsd-summary`                                            |
| `s30a` | 23:54:31Z | `s30a-control-minimal-end`                       | control             | `MINIMAL_PARTS`                                                                                                                                                                                                    | `4220be34a673ce8b` | clean-open     | valid                        | valid                                                                                               |

<details><summary>Raw records, session 30</summary>

```jsonl
{"run": "s30a", "name": "s30a-control-minimal", "sha256": "4220be34a673ce8bc1b4d4c2d3c580bde680b5d8e4f39ab8cf6a8ecb6d96e8e5", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s30a", "name": "glossary-footerref-footer-rel-ftr-typed-footer", "sha256": "01abfee9a52827505b04378fd2e1ab01f84995cdc9bf8265b6b5c5c73f509053", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s30a", "name": "dup-id-glossary-sidecar", "sha256": "f10d8c7646699480d16fcd6e2526cda71065c5a68075842649004e3e4266f109", "observedAt": "2026-10-24T23:53:53.791Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__dup-id-glossary-sidecar.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__dup-id-glossary-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__dup-id-glossary-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s30a", "name": "relocated-main-transitional", "sha256": "231e9873ec77f2b57b002b3a4ce8e464c54e5302f09bb0dcba61bca6ea3b60a6", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s30a", "name": "relocated-main-orphan-sidecar", "sha256": "7ffd994eaebdc1757d4574d9efe3eef15fcd04672600b7813547b525ca6f715c", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s30a", "name": "dup-id-non-main-document-sidecar", "sha256": "7c240516e15e401bfee04e3a3483f0bb6cc8d74254f8a7e1da60e9f9d6bb5ef7", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s30a", "name": "dup-id-relocated-main-transitional", "sha256": "cf7b780037c2c6b566eca03a44e84404697665bd08c942e1cb8404790256bf93", "observedAt": "2026-10-24T23:54:18.359Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__dup-id-relocated-main-transitional.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00002__wfv__dup-id-relocated-main-transitional.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "'Word found unreadable content in 00002__wfv__dup-id-relocated-main-transitional.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'"]}
{"run": "s30a", "name": "s30a-control-minimal-end", "sha256": "4220be34a673ce8bc1b4d4c2d3c580bde680b5d8e4f39ab8cf6a8ecb6d96e8e5", "observedAt": "2026-10-24T23:54:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 31: 00:26Z on 2026-10-25, validator columns at ceb5c884

Adversarial review BC's suspected item on #617: duplicate relationship Ids beside a main document or a reached glossary stored without a `.xml` suffix (S1, #618).

| Run    | Observed  | Specimen                      | Issue               | Shape                                                                                                                                                                | SHA-256 (first 16) | Word           | word-valid at ceb5c884 | strict at ceb5c884                                            |
| ------ | --------- | ----------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ---------------------- | ------------------------------------------------------------- |
| `s31a` | 00:26:46Z | `s31a-control-minimal`        | control             | `MINIMAL_PARTS`                                                                                                                                                      | `42040cd5e6236bba` | clean-open     | valid                  | valid                                                         |
| `s31a` | 00:26:46Z | `bin-main`                    | control             | `MINIMAL_PARTS` with the main document stored as `word/document.bin` (package relationship, Override and sidecar renamed with it)                                    | `c7e3e0ac3cacc9e3` | clean-open     | valid                  | valid                                                         |
| `s31a` | 00:26:44Z | `dup-id-bin-main-sidecar`     | #618 (review BC S1) | the same plus two unreferenced External hyperlink relationships sharing `rIdZ` in `word/_rels/document.bin.rels`                                                     | `646d74ac90722184` | repair-warning | valid                  | invalid: `xsd-error`, `xsd-summary`                           |
| `s31a` | 00:26:46Z | `bin-glossary`                | control             | session 26's clean glossary footer shape with the glossary stored as `word/glossary/document.bin` (main-document relationship, Override and sidecar renamed with it) | `e7da83dbb8652152` | clean-open     | valid                  | invalid: `paraid-missing-element`                             |
| `s31a` | 00:26:34Z | `dup-id-bin-glossary-sidecar` | #618 (review BC S1) | the same plus two unreferenced External hyperlink relationships sharing `rIdZ` in `word/glossary/_rels/document.bin.rels`                                            | `9cffc98ee7d0ed36` | repair-warning | valid                  | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary` |
| `s31a` | 00:26:46Z | `s31a-control-minimal-end`    | control             | `MINIMAL_PARTS`                                                                                                                                                      | `42040cd5e6236bba` | clean-open     | valid                  | valid                                                         |

<details><summary>Raw records, session 31</summary>

```jsonl
{"run": "s31a", "name": "s31a-control-minimal", "sha256": "42040cd5e6236bbac1acff975cec03791c5e6ca85c41d7e2cd71d47f2b8bf0aa", "observedAt": "2026-10-25T00:26:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s31a", "name": "bin-main", "sha256": "c7e3e0ac3cacc9e34bee93099058f514928da263e8655fa24ed873f03bbb0aa6", "observedAt": "2026-10-25T00:26:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s31a", "name": "dup-id-bin-main-sidecar", "sha256": "646d74ac90722184ade62383362f5a6a88c438f3f67d94833264abb61a433bf3", "observedAt": "2026-10-25T00:26:44.295Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__dup-id-bin-main-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__dup-id-bin-main-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s31a", "name": "bin-glossary", "sha256": "e7da83dbb8652152e4db328fa8e07716e1847cba0029aabef48d63a2f4016e45", "observedAt": "2026-10-25T00:26:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s31a", "name": "dup-id-bin-glossary-sidecar", "sha256": "9cffc98ee7d0ed36cbf1cde2138596ba51bdd24fa5967556caafb903b02ab980", "observedAt": "2026-10-25T00:26:34.209Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__dup-id-bin-glossary-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__dup-id-bin-glossary-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s31a", "name": "s31a-control-minimal-end", "sha256": "42040cd5e6236bbac1acff975cec03791c5e6ca85c41d7e2cd71d47f2b8bf0aa", "observedAt": "2026-10-25T00:26:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 32: 01:10Z on 2026-10-25, validator columns at 6e3cda3e

Adversarial review BD's suspected items on #618: a main document stored as `word/document.bin` that is malformed or whose footer reference names no relationship (S1, S2, #620), with `.xml` twins, one of which found #619.

| Run    | Observed  | Specimen                       | Issue               | Shape                                                                                                                                                                           | SHA-256 (first 16) | Word           | word-valid at 6e3cda3e          | strict at 6e3cda3e                                   |
| ------ | --------- | ------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------- | ---------------------------------------------------- |
| `s32a` | 01:11:36Z | `s32a-control-minimal`         | control             | `MINIMAL_PARTS`                                                                                                                                                                 | `a04b2b9a2dd67f36` | clean-open     | valid                           | valid                                                |
| `s32a` | 01:11:14Z | `main-truncated`               | calibration         | `MINIMAL_PARTS` with the main document's closing `</w:body></w:document>` removed                                                                                               | `2fc91055bcc3cd1d` | open-error     | invalid: `xml-syntax`           | invalid: `xml-syntax`                                |
| `s32a` | 01:10:54Z | `bin-main-truncated`           | #620 (review BD S1) | the same, stored as `word/document.bin` (package relationship, Override and `.rels` renamed with it)                                                                            | `5267572bb13cdb09` | open-error     | valid                           | valid                                                |
| `s32a` | 01:11:10Z | `footerref-rid-no-sidecar`     | calibration         | `MINIMAL_PARTS` with `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr` (`xmlns:r` declared) and `word/_rels/document.xml.rels` removed           | `903c4db913c067af` | repair-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `rels-unreferenced` |
| `s32a` | 01:10:50Z | `bin-footerref-rid-no-sidecar` | #620 (review BD S2) | the same, stored as `word/document.bin` (package relationship, Override and `.rels` renamed with it)                                                                            | `8881f8614c3db73d` | repair-warning | valid                           | invalid: `rels-unreferenced`                         |
| `s32a` | 01:10:58Z | `footerref-rid-missing`        | #619                | `MINIMAL_PARTS` with `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr` (`xmlns:r` declared); `word/_rels/document.xml.rels` kept, with no `rId9` | `4969aeee012d3c81` | repair-warning | valid                           | invalid: `rels-id-missing`                           |
| `s32a` | 01:10:39Z | `bin-footerref-rid-missing`    | #620 (review BD S2) | the same, stored as `word/document.bin` (package relationship, Override and `.rels` renamed with it)                                                                            | `8d94ffcffc55cadc` | repair-warning | valid                           | valid                                                |
| `s32a` | 01:11:36Z | `s32a-control-minimal-end`     | control             | `MINIMAL_PARTS`                                                                                                                                                                 | `a04b2b9a2dd67f36` | clean-open     | valid                           | valid                                                |

<details><summary>Raw records, session 32</summary>

```jsonl
{"run": "s32a", "name": "s32a-control-minimal", "sha256": "a04b2b9a2dd67f365eed13da3044f8c4e0761de0183851dc866f505131e6612f", "observedAt": "2026-10-25T01:11:36+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s32a", "name": "main-truncated", "sha256": "2fc91055bcc3cd1d4e8e82cd09cc5a56f6026660ab6718fdcccb73c1e9c88da3", "observedAt": "2026-10-25T01:11:14.632Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__main-truncated.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "bin-main-truncated", "sha256": "5267572bb13cdb09dc4c53c149c410e2ad9882d934a21cf77d7802368c9fcca6", "observedAt": "2026-10-25T01:10:54.305Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__bin-main-truncated.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "footerref-rid-no-sidecar", "sha256": "903c4db913c067af9c8a6e7403b4ae2835c662ade89679d81cb929a555a4f885", "observedAt": "2026-10-25T01:11:10.339Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__footerref-rid-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__footerref-rid-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "bin-footerref-rid-no-sidecar", "sha256": "8881f8614c3db73dce86b8d28a6ecd7560941ed75968e6e78d4eaa8161a15e98", "observedAt": "2026-10-25T01:10:50.022Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__bin-footerref-rid-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__bin-footerref-rid-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "footerref-rid-missing", "sha256": "4969aeee012d3c81918e009c35850789f140b302c762caadb09b140e50394b75", "observedAt": "2026-10-25T01:10:58.681Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__footerref-rid-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__footerref-rid-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "bin-footerref-rid-missing", "sha256": "8d94ffcffc55cadc13f5bf07e6b0086aef57b577894d5c676d20a1c88f9ca75c", "observedAt": "2026-10-25T01:10:39.867Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__bin-footerref-rid-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__bin-footerref-rid-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s32a", "name": "s32a-control-minimal-end", "sha256": "a04b2b9a2dd67f365eed13da3044f8c4e0761de0183851dc866f505131e6612f", "observedAt": "2026-10-25T01:11:36+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 33: 04:45Z–05:23Z on 2026-10-25, validator columns at 8b79bc78

Adversarial reviews BE and BG's suspected items on #619 (#623, #624, #625, #631, #632), with clean controls in every chunk. The driver opens each chunk's files in name order, so the controls were queued 4th and 5th of 8 in `s33a`, last in `s33b` and `s33e`, 5th and 6th of 8 in `s33c`, and 3rd and 4th of 6 in `s33d` ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). In every chunk Word stalled or crashed on a specimen, and the driver reopened it in a later pass, after the rest of the queue, so a specimen reopened after both controls ([#672](https://github.com/jandira-tech/docx-validate/issues/672)). `s33c`–`s33e` were built at 5cd8ada8, whose tree is 8b79bc78's, so one pair of validator columns holds for every chunk. Where a specimen renders, the PDF Word wrote says whether Word read the reference: session 26's footer prints "Footer" under the minimal document's "Hello".

| Run    | Observed  | Specimen                                | Issue            | Shape                                                                                                                                                                                                                                                                                                                            | SHA-256 (first 16) | Word           | word-valid at 8b79bc78                                            | strict at 8b79bc78                                                                                                                   |
| ------ | --------- | --------------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `s33a` | 04:55:46Z | `s33a-control-minimal`                  | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `62d6964cbc054c6c` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33a` | 04:55:46Z | `footerref-rid-empty`                   | #623             | `MINIMAL_PARTS` with `<w:footerReference w:type="default" r:id=""/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                           | `20d261e8a03fa0f6` | inconclusive   | valid                                                             | valid                                                                                                                                |
| `s33a` | 04:51:28Z | `headerref-rid-empty`                   | #623             | `MINIMAL_PARTS` with `<w:headerReference w:type="default" r:id=""/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                           | `d5f058acb7650b99` | repair-warning | valid                                                             | valid                                                                                                                                |
| `s33a` | 04:55:46Z | `footerref-no-rid`                      | #623             | `MINIMAL_PARTS` with `<w:footerReference w:type="default"/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                                   | `610b20aff6b66a83` | inconclusive   | valid                                                             | invalid: `xsd-error`, `xsd-summary`                                                                                                  |
| `s33a` | 04:55:46Z | `strict-ns-control`                     | #624 control     | `MINIMAL_PARTS` with the main document and styles in the ISO Strict WordprocessingML namespace                                                                                                                                                                                                                                   | `64059786e25ced46` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33a` | 04:51:45Z | `strict-ns-footerref-no-sidecar`        | #624             | `MINIMAL_PARTS` with the main document and styles in the ISO Strict WordprocessingML namespace and `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr`, `xmlns:r` bound to the ISO Strict relationships namespace; `word/_rels/document.xml.rels` removed                                           | `ee695800235463de` | repair-warning | valid                                                             | invalid: `rels-unreferenced`                                                                                                         |
| `s33a` | 04:55:46Z | `strict-ns-footerref-rid-missing`       | #624 calibration | `MINIMAL_PARTS` with the main document and styles in the ISO Strict WordprocessingML namespace and `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr`, `xmlns:r` bound to the ISO Strict relationships namespace; `word/_rels/document.xml.rels` kept, with no `rId9`                              | `ea9e8cbba27cf64d` | inconclusive   | invalid: `word-header-footer-relationship`                        | invalid: `word-header-footer-relationship`                                                                                           |
| `s33a` | 04:55:46Z | `s33a-control-minimal-end`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `0f1790875ce86ac2` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33b` | 05:05:06Z | `s33b-control-minimal`                  | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `117da91a4fb5d5a5` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33b` | 05:05:06Z | `header1-main-control`                  | #625 control     | `MINIMAL_PARTS`, the main document stored as `word/header1.xml` (its package relationship, `.rels` and Override renamed with it)                                                                                                                                                                                                 | `34112a09b4fc2080` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33b` | 05:04:14Z | `header1-main-footerref-no-sidecar`     | #625             | `MINIMAL_PARTS` with `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr` (`xmlns:r` declared), the main document stored as `word/header1.xml` (its package relationship, `.rels` and Override renamed with it); its `.rels` removed                                                                 | `c3b0be9d7e2859a0` | repair-warning | valid                                                             | invalid: `rels-missing-sidecar`, `rels-unreferenced`                                                                                 |
| `s33b` | 05:05:06Z | `header1-glossary-control`              | #625 control     | session 26's reached glossary (`glossaryStoryReferenceParts`, footer `word/glossary/footer9.xml`), the glossary stored as `word/header1.xml` (its glossary relationship, `.rels` and Override renamed with it)                                                                                                                   | `52db5b7234ab17c6` | clean-open     | valid                                                             | invalid: `paraid-missing-element`                                                                                                    |
| `s33b` | 05:05:05Z | `header1-glossary-footerref-no-sidecar` | #625             | the same; its `.rels` removed, which leaves the glossary's footer reference dangling                                                                                                                                                                                                                                             | `012d06e4565f3e3b` | repair-warning | valid                                                             | invalid: `paraid-missing-element`, `rels-missing-sidecar`, `rels-unreferenced`                                                       |
| `s33b` | 05:03:36Z | `glossary-footerref-no-sidecar`         | #625 calibration | session 26's reached glossary (`glossaryStoryReferenceParts`, footer `word/glossary/footer9.xml`) with `word/glossary/_rels/document.xml.rels` removed                                                                                                                                                                           | `91b27f6607ff056b` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `paraid-missing-element`, `rels-missing-sidecar`, `rels-unreferenced`                                                       |
| `s33b` | 05:05:06Z | `s33b-control-minimal-end`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `4cd61da586f4857f` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33c` | 05:15:31Z | `s33c-control-minimal`                  | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `2bf7835b89ccd6eb` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33c` | 05:14:12Z | `footerref-no-rid`                      | #623             | `MINIMAL_PARTS` with `<w:footerReference w:type="default"/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                                   | `22586d7da00e7bde` | open-error     | valid                                                             | invalid: `xsd-error`, `xsd-summary`                                                                                                  |
| `s33c` | 05:14:21Z | `footerref-rid-empty`                   | #623             | `MINIMAL_PARTS` with `<w:footerReference w:type="default" r:id=""/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                           | `be5035ebad4664e4` | repair-warning | valid                                                             | valid                                                                                                                                |
| `s33c` | 05:15:14Z | `strict-ns-footerref-rid-missing`       | #624 calibration | `MINIMAL_PARTS` with the main document and styles in the ISO Strict WordprocessingML namespace and `<w:footerReference w:type="default" r:id="rId9"/>` first in the body `w:sectPr`, `xmlns:r` bound to the ISO Strict relationships namespace; `word/_rels/document.xml.rels` kept, with no `rId9`                              | `94f722cfd23b6fd5` | repair-warning | invalid: `word-header-footer-relationship`                        | invalid: `word-header-footer-relationship`                                                                                           |
| `s33c` | 05:15:31Z | `strict-ns-no-rels-no-reference`        | #624 isolation   | `MINIMAL_PARTS` with the main document and styles in the ISO Strict WordprocessingML namespace; `word/_rels/document.xml.rels` removed; no reference                                                                                                                                                                             | `1b704859bd7a2a52` | clean-open     | valid                                                             | invalid: `rels-unreferenced`                                                                                                         |
| `s33c` | 05:14:59Z | `rs-id-dangling`                        | #631             | `MINIMAL_PARTS` with `<w:footerReference w:type="default" rs:id="rId9"/>` first in the body `w:sectPr` (`xmlns:rs` bound to the ISO Strict relationships namespace, no `r` binding)                                                                                                                                              | `5dcdcbfea05fd46a` | repair-warning | invalid: `word-header-footer-relationship`                        | invalid: `word-header-footer-relationship`, `xsd-error`, `xsd-summary`                                                               |
| `s33c` | 05:15:31Z | `rs-id-valid-footer`                    | #631             | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`), its `r:id` replaced by `rs:id="rIdX"` (ISO Strict relationships namespace)                                                                                                                                        | `e985b7ca10dcebe0` | clean-open     | valid                                                             | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                                        |
| `s33c` | 05:15:31Z | `s33c-control-minimal-end`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `2bf7835b89ccd6eb` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33d` | 05:16:40Z | `s33d-control-minimal`                  | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `2bf7835b89ccd6eb` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33d` | 05:16:40Z | `footer-valid-calibration`              | calibration      | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`)                                                                                                                                                                                                                    | `c4c60ce37c69eb87` | clean-open     | valid                                                             | invalid: `paraid-missing-element`                                                                                                    |
| `s33d` | 05:16:40Z | `mce-rels-fallback-footer`              | #632             | the same, with the `rIdX` Relationship moved into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`) in `word/_rels/document.xml.rels`                                                                                                                 | `3be051611e976a51` | clean-open     | invalid: `opc-relationships-structure`                            | invalid: `opc-relationships-structure`, `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`                             |
| `s33d` | 05:16:18Z | `third-ns-id-dangling`                  | #623 (#632 S-C)  | `MINIMAL_PARTS` with `<w:footerReference w:type="default" x:id="rId9"/>` first in the body `w:sectPr` (`xmlns:x="urn:x"`)                                                                                                                                                                                                        | `4090c9c464c19842` | open-error     | valid                                                             | invalid: `xsd-error`, `xsd-summary`                                                                                                  |
| `s33d` | 05:16:23Z | `third-ns-id-valid-footer`              | #623 (#632 S-C)  | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`), its `r:id` replaced by `x:id="rIdX"` (`xmlns:x="urn:x"`)                                                                                                                                                          | `c208e286b7a17752` | open-error     | valid                                                             | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                                        |
| `s33d` | 05:16:40Z | `s33d-control-minimal-end`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `2bf7835b89ccd6eb` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33e` | 05:23:20Z | `s33e-control-minimal`                  | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `a01ef3841cc4a9c2` | clean-open     | valid                                                             | valid                                                                                                                                |
| `s33e` | 05:22:17Z | `headerref-no-rid`                      | #623             | `MINIMAL_PARTS` with `<w:headerReference w:type="default"/>` first in the body `w:sectPr` (`xmlns:r` declared)                                                                                                                                                                                                                   | `32010c227a7ffb7c` | open-error     | valid                                                             | invalid: `xsd-error`, `xsd-summary`                                                                                                  |
| `s33e` | 05:23:20Z | `mce-package-rels-fallback-main`        | #632             | `MINIMAL_PARTS` with `_rels/.rels`'s officeDocument Relationship moved into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`)                                                                                                                         | `d55ee3a1ee7174bc` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure`, `rels-unreferenced`, `word-main-document-part`, `xsd-error`, `xsd-summary`                   |
| `s33e` | 05:23:20Z | `mce-rels-choice-w14-footer`            | #632             | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`), the `rIdX` Relationship moved into `<mc:AlternateContent><mc:Choice Requires="w14">…</mc:Choice><mc:Fallback/></mc:AlternateContent>` (`w14` = `http://schemas.microsoft.com/office/word/2010/wordml`)            | `9b5d6066c5849178` | clean-open     | invalid: `opc-relationships-structure`                            | invalid: `opc-relationships-structure`, `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`                             |
| `s33e` | 05:23:20Z | `mce-rels-ignorable-foreign`            | #632             | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`), plus a foreign `<x:Wrap/>` after the Relationships, the root declaring `xmlns:x="urn:x"` and `mc:Ignorable="x"`                                                                                                   | `cfa548e94f66d305` | clean-open     | invalid: `opc-relationships-structure`                            | invalid: `opc-relationships-structure`, `paraid-missing-element`                                                                     |
| `s33e` | 05:22:38Z | `mce-rels-fallback-foreign`             | #632             | session 26's clean footer (`storyReferenceParts`: `r:id="rIdX"`, a footer relationship to `word/footer1.xml`), the `rIdX` Relationship and a foreign `<x:Wrap/>` both moved into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`, `xmlns:x="urn:x"`) | `00f74391cdc0863c` | repair-warning | invalid: `opc-relationships-structure`                            | invalid: `opc-relationships-structure`, `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s33e` | 05:23:20Z | `s33e-control-minimal-end`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                  | `f18ce8ddd7bf7056` | clean-open     | valid                                                             | valid                                                                                                                                |

<details><summary>Raw records, session 33</summary>

```jsonl
{"run": "s33a", "name": "s33a-control-minimal", "sha256": "62d6964cbc054c6cc77c060d129973857a0f053b9b005afe7b307f265b9e3de8", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33a", "name": "footerref-rid-empty", "sha256": "20d261e8a03fa0f6333de99dd3fa06362e6a30fb1f7412b6911c8ffd2f69ef86", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "other", "item": "failed", "error": "Microsoft Word got an error: AppleEvent timed out.", "dialogs": []}
{"run": "s33a", "name": "headerref-rid-empty", "sha256": "d5f058acb7650b990dfc2d68d6124f36ea8b580952f24a5e39b823ae71a7bd52", "observedAt": "2026-10-25T04:51:28.203Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__headerref-rid-empty.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__headerref-rid-empty.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__headerref-rid-empty.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33a", "name": "footerref-no-rid", "sha256": "610b20aff6b66a83a3a8ee8d5c1595b84c22fb09020addbe23cda39bfa2a4d60", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "other", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00000__wfv__footerref-no-rid.docx; refusing to guess", "dialogs": []}
{"run": "s33a", "name": "strict-ns-control", "sha256": "64059786e25ced460debcce1d28efe8b39a3a817dc9be7f54b67cd73e1c64fb6", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33a", "name": "strict-ns-footerref-no-sidecar", "sha256": "ee695800235463de7cf2daf884fd41d0143a59ee6d1725d4302d2f87464ce200", "observedAt": "2026-10-25T04:51:45.864Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__strict-ns-footerref-no-sidecar.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word found unreadable content in 00006__wfv__strict-ns-footerref-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s33a", "name": "strict-ns-footerref-rid-missing", "sha256": "ea9e8cbba27cf64d690ad50db7b3771d9c6f028f93392c450ee4cca1b192c10b", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "other", "item": "failed", "error": "Microsoft Word got an error: AppleEvent timed out.", "dialogs": []}
{"run": "s33a", "name": "s33a-control-minimal-end", "sha256": "0f1790875ce86ac26d5eee297f14432f226e71804acbee5296808a9958280490", "observedAt": "2026-10-25T04:55:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33b", "name": "s33b-control-minimal", "sha256": "117da91a4fb5d5a5bf4931313277f891f040df4c0a6b08effd2c4c39a1ebb13f", "observedAt": "2026-10-25T05:05:06+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33b", "name": "header1-main-control", "sha256": "34112a09b4fc2080c6ee80684804679d86af606ff27f73f4181389cba5b18194", "observedAt": "2026-10-25T05:05:06+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33b", "name": "header1-main-footerref-no-sidecar", "sha256": "c3b0be9d7e2859a0236c9a6e34789ab1ab40e46199c8b4ef260294578a98110c", "observedAt": "2026-10-25T05:04:14.370Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__header1-main-footerref-no-sidecar.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00004__wfv__header1-main-footerref-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__header1-main-footerref-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33b", "name": "header1-glossary-control", "sha256": "52db5b7234ab17c646e4d07dd0243fc4aefe0cd20987756be646f5cf27a75324", "observedAt": "2026-10-25T05:05:06+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33b", "name": "header1-glossary-footerref-no-sidecar", "sha256": "012d06e4565f3e3b7d98f3872f62db2e4951aa9903e01dd9d5cc036befe89a20", "observedAt": "2026-10-25T05:05:05.914Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__header1-glossary-footerref-no-sidecar.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__header1-glossary-footerref-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'"]}
{"run": "s33b", "name": "glossary-footerref-no-sidecar", "sha256": "91b27f6607ff056b1ad755f636b9179f6b03b08dfd36b4b7bf4f52da217ea2ff", "observedAt": "2026-10-25T05:03:36.479Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__glossary-footerref-no-sidecar.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00000__wfv__glossary-footerref-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33b", "name": "s33b-control-minimal-end", "sha256": "4cd61da586f4857fc15d9e4e62c3dc989f9cb3adec0fb43be0a450076fbf41fa", "observedAt": "2026-10-25T05:05:06+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33c", "name": "s33c-control-minimal", "sha256": "2bf7835b89ccd6eb9930f55cac357ec14e44cb50a4a83c053aaefa9511e0beae", "observedAt": "2026-10-25T05:15:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33c", "name": "footerref-no-rid", "sha256": "22586d7da00e7bdeaba308120f103e54936934f21b2f8d7778deb2742b2b788f", "observedAt": "2026-10-25T05:14:12.925Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00000__wfv__footerref-no-rid.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33c", "name": "footerref-rid-empty", "sha256": "be5035ebad4664e4c8641946d119849cb1ae8d7e530efd1262ec7d524542251c", "observedAt": "2026-10-25T05:14:21.668Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__footerref-rid-empty.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word found unreadable content in 00001__wfv__footerref-rid-empty.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33c", "name": "strict-ns-footerref-rid-missing", "sha256": "94f722cfd23b6fd589f5d2818f2d1d0e3995a26ed3bc1daf9337ee651c4a295b", "observedAt": "2026-10-25T05:15:14.223Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00006__wfv__strict-ns-footerref-rid-missing.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33c", "name": "strict-ns-no-rels-no-reference", "sha256": "1b704859bd7a2a52fcfc518bfed7c8ad0b2d907a5cce4d7d065c661edbcf6cd6", "observedAt": "2026-10-25T05:15:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33c", "name": "rs-id-dangling", "sha256": "5dcdcbfea05fd46aa89f5b855764d2e8a5a64f3275f99ca00ce2e852e6be8f91", "observedAt": "2026-10-25T05:14:59.542Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word found unreadable content in 00002__wfv__rs-id-dangling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s33c", "name": "rs-id-valid-footer", "sha256": "e985b7ca10dcebe03394add4b787136119f9f9abbdd68597854a10fa2d1250e9", "observedAt": "2026-10-25T05:15:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33c", "name": "s33c-control-minimal-end", "sha256": "2bf7835b89ccd6eb9930f55cac357ec14e44cb50a4a83c053aaefa9511e0beae", "observedAt": "2026-10-25T05:15:31+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33d", "name": "s33d-control-minimal", "sha256": "2bf7835b89ccd6eb9930f55cac357ec14e44cb50a4a83c053aaefa9511e0beae", "observedAt": "2026-10-25T05:16:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33d", "name": "footer-valid-calibration", "sha256": "c4c60ce37c69eb87cd2ff5595dbca3349952227eb00bc217f8b2c04e6bef6c69", "observedAt": "2026-10-25T05:16:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33d", "name": "mce-rels-fallback-footer", "sha256": "3be051611e976a51121d7bde1f67b232bd089dbe8524ccbd6fa01708c5b968e8", "observedAt": "2026-10-25T05:16:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33d", "name": "third-ns-id-dangling", "sha256": "4090c9c464c1984207ed12b61d6d07a7c496e1b5edf0774d12fa6c9eac470594", "observedAt": "2026-10-25T05:16:18.532Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__third-ns-id-dangling.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33d", "name": "third-ns-id-valid-footer", "sha256": "c208e286b7a17752fffb18c201258335fbeea9caed1b0533fa3a82f0f70cc99f", "observedAt": "2026-10-25T05:16:23.574Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__third-ns-id-valid-footer.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s33d", "name": "s33d-control-minimal-end", "sha256": "2bf7835b89ccd6eb9930f55cac357ec14e44cb50a4a83c053aaefa9511e0beae", "observedAt": "2026-10-25T05:16:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33e", "name": "s33e-control-minimal", "sha256": "a01ef3841cc4a9c20a352c55a5a37fa5014338d12ae59a0c88cca9dcc4d5b1aa", "observedAt": "2026-10-25T05:23:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33e", "name": "headerref-no-rid", "sha256": "32010c227a7ffb7c1014aef0972d8ef61f7bcb67e69fc3c48dee2002a0494aba", "observedAt": "2026-10-25T05:22:17.533Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00000__wfv__headerref-no-rid.docx; refusing to guess", "dialogs": ["\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter.", "'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver"]}
{"run": "s33e", "name": "mce-package-rels-fallback-main", "sha256": "d55ee3a1ee7174bcce382111c7c7f583c67ab386df5d4e03e8f0042052e9fad8", "observedAt": "2026-10-25T05:23:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33e", "name": "mce-rels-choice-w14-footer", "sha256": "9b5d6066c5849178cb1fb967ea1012f19b6936b11ef9b1eab7689eec48a85752", "observedAt": "2026-10-25T05:23:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33e", "name": "mce-rels-ignorable-foreign", "sha256": "cfa548e94f66d305749469d3891d5b438e51837d72c05ee336f3b20061588e8a", "observedAt": "2026-10-25T05:23:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s33e", "name": "mce-rels-fallback-foreign", "sha256": "00f74391cdc0863c6b83b2de5c1dd1329bf47640a69293ad31e3ca9a8699406a", "observedAt": "2026-10-25T05:22:38.588Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__mce-rels-fallback-foreign.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00003__wfv__mce-rels-fallback-foreign.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s33e", "name": "s33e-control-minimal-end", "sha256": "f18ce8ddd7bf7056130e594838744ca3b1f772270d0ae38b1daaa8c49db024be", "observedAt": "2026-10-25T05:23:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 34: 06:02Z–06:09Z on 2026-10-25, validator columns at ef5d8107

The adversarial review of #632's fix (empryo devin/swe-2), findings 1, 2 and 4 (#634, #635, #636), each wrapped shape beside its direct twin, with clean controls in every chunk. The specimens sort before their chunk's controls, so the controls were queued last: two each in `s34a` and `s34b`, and the one control in each of `s34c` and `s34d` ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). In `s34a` and `s34b` Word stalled or crashed on a specimen, and the driver reopened it in a later pass, after the controls ([#672](https://github.com/jandira-tech/docx-validate/issues/672)). In `s34c` Word crashed on the control after the specimen's declined recovery offer, and the control opened clean after the driver relaunched Word ([#673](https://github.com/jandira-tech/docx-validate/issues/673)).

| Run    | Observed  | Specimen                            | Issue            | Shape                                                                                                                                                                                                                                                                                                               | SHA-256 (first 16) | Word                        | word-valid at ef5d8107                     | strict at ef5d8107                                                                                                                                   |
| ------ | --------- | ----------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | --------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s34a` | 06:05:12Z | `s34a-control-minimal`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `478df25aa6503642` | clean-open                  | valid                                      | valid                                                                                                                                                |
| `s34a` | 06:04:21Z | `mce-fallback-main-malformed-doc`   | #634             | `MINIMAL_PARTS` with `_rels/.rels`'s officeDocument Relationship moved into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`); `word/document.xml` truncated to `<w:document …><w:body><w:p>`                                            | `5de3536778f4a45c` | open-error                  | valid                                      | invalid: `opc-relationships-markup-compatibility`, `rels-unreferenced`, `xml-syntax`, `xsd-error`, `xsd-summary`                                     |
| `s34a` | 06:04:05Z | `direct-main-malformed-doc`         | #634 twin        | `MINIMAL_PARTS` with `word/document.xml` truncated to `<w:document …><w:body><w:p>`                                                                                                                                                                                                                                 | `5614b876b20a59da` | open-error                  | invalid: `xml-syntax`                      | invalid: `xml-syntax`                                                                                                                                |
| `s34a` | 06:04:26Z | `mce-fallback-main-zerobyte-rels`   | #634             | `MINIMAL_PARTS` with `_rels/.rels`'s officeDocument Relationship moved into `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`); `word/_rels/document.xml.rels` zero bytes                                                                 | `79ee3843a83ef05c` | repair-warning              | valid                                      | invalid: `opc-relationships-markup-compatibility`, `rels-id-parse`, `rels-unreferenced`, `xml-syntax`, `xsd-error`, `xsd-summary`                    |
| `s34a` | 06:04:11Z | `direct-main-zerobyte-rels`         | #634 twin        | `MINIMAL_PARTS` with `word/_rels/document.xml.rels` zero bytes                                                                                                                                                                                                                                                      | `c4f0d4f910599079` | repair-warning              | invalid: `xml-syntax`                      | invalid: `rels-id-parse`, `rels-unreferenced`, `xml-syntax`                                                                                          |
| `s34a` | 06:04:36Z | `mce-fallback-split-duplicate-id`   | #635             | `MINIMAL_PARTS` with `_rels/.rels` holding a direct `rId1` officeDocument Relationship and an `rId1` styles Relationship inside `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`)                                                        | `e3635fd614c69c58` | repair-warning              | valid                                      | invalid: `opc-relationships-markup-compatibility`, `xsd-error`, `xsd-summary`                                                                        |
| `s34a` | 06:03:10Z | `direct-duplicate-id`               | #635 twin        | `MINIMAL_PARTS` with `_rels/.rels` holding two direct `rId1` Relationships (officeDocument, styles)                                                                                                                                                                                                                 | `5d4151891441e71b` | repair-warning              | invalid: `rels-id-duplicate`               | invalid: `rels-id-duplicate`, `xsd-error`, `xsd-summary`                                                                                             |
| `s34a` | 06:05:12Z | `s34a-control-minimal-end`          | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `39a5184664dcf46f` | clean-open                  | valid                                      | valid                                                                                                                                                |
| `s34b` | 06:08:28Z | `s34b-control-minimal`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `39a5184664dcf46f` | clean-open                  | valid                                      | valid                                                                                                                                                |
| `s34b` | 06:07:21Z | `mce-fallback-malformed-coreprops`  | #634             | `MINIMAL_PARTS` with a core-properties Relationship (`rIdC`) to `docProps/core.xml`, its Override added, and `docProps/core.xml` truncated inside `dc:title`; the Relationship inside `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`)  | `e371880140b48156` | repair-warning              | valid                                      | invalid: `opc-relationships-markup-compatibility`, `rels-unreferenced`, `xml-syntax`, `xsd-error`, `xsd-summary`                                     |
| `s34b` | 06:06:23Z | `direct-malformed-coreprops`        | #634 twin        | `MINIMAL_PARTS` with a core-properties Relationship (`rIdC`) to `docProps/core.xml`, its Override added, and `docProps/core.xml` truncated inside `dc:title`; the Relationship direct                                                                                                                               | `f7930cf3cc8f6f7b` | repair-warning              | invalid: `xml-syntax`                      | invalid: `xml-syntax`                                                                                                                                |
| `s34b` | 06:07:11Z | `mce-fallback-footer-header-ct`     | #634             | session 26's footer (`storyReferenceParts`: `r:id="rIdX"` to `word/footer1.xml`) whose Override types it as a header; the `rIdX` Relationship inside `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (`xmlns:foo="urn:foo"`) in `word/_rels/document.xml.rels` | `0da480e77533fc65` | repair-warning              | valid                                      | invalid: `opc-relationships-markup-compatibility`, `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`                                  |
| `s34b` | 06:05:30Z | `direct-footer-header-ct`           | #634 twin (#600) | session 26's footer (`storyReferenceParts`: `r:id="rIdX"` to `word/footer1.xml`) whose Override types it as a header; the Relationship direct                                                                                                                                                                       | `5b931e0c8dd4fd2e` | repair-warning              | invalid: `word-part-content-type-mismatch` | invalid: `paraid-missing-element`, `word-part-content-type-mismatch`                                                                                 |
| `s34b` | 06:08:28Z | `mce-rels-root-mustunderstand`      | #636             | `MINIMAL_PARTS` with `xmlns:mc`, `xmlns:foo="urn:foo"` and `mc:MustUnderstand="foo"` on the `_rels/.rels` root                                                                                                                                                                                                      | `c27cdf562eda5210` | Word crashed (inconclusive) | valid                                      | invalid: `xsd-error`, `xsd-summary`                                                                                                                  |
| `s34b` | 06:08:25Z | `mce-rels-choice-undeclared-prefix` | #636             | session 26's clean footer, the `rIdX` Relationship moved into `<mc:AlternateContent><mc:Choice Requires="nope">…</mc:Choice><mc:Fallback/></mc:AlternateContent>`, `nope` undeclared                                                                                                                                | `fe8c495cf8d607d3` | repair-warning              | invalid: `word-header-footer-relationship` | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `paraid-missing-element`, `rels-unreferenced`, `word-header-footer-relationship` |
| `s34b` | 06:08:28Z | `s34b-control-minimal-end`          | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `a9d7b233ab836929` | clean-open                  | valid                                      | valid                                                                                                                                                |
| `s34c` | 06:09:15Z | `mce-rels-root-mustunderstand`      | #636             | `MINIMAL_PARTS` with `xmlns:mc`, `xmlns:foo="urn:foo"` and `mc:MustUnderstand="foo"` on the `_rels/.rels` root                                                                                                                                                                                                      | `84f47433da625890` | repair-warning              | valid                                      | invalid: `xsd-error`, `xsd-summary`                                                                                                                  |
| `s34c` | 06:09:20Z | `s34c-control-minimal`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `340f2f996aa63965` | clean-open                  | valid                                      | valid                                                                                                                                                |
| `s34d` | 06:09:37Z | `mce-rels-choice-undeclared-prefix` | #636             | session 26's clean footer, the `rIdX` Relationship moved into `<mc:AlternateContent><mc:Choice Requires="nope">…</mc:Choice><mc:Fallback/></mc:AlternateContent>`, `nope` undeclared                                                                                                                                | `961d1b7b77cd7379` | repair-warning              | invalid: `word-header-footer-relationship` | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `paraid-missing-element`, `rels-unreferenced`, `word-header-footer-relationship` |
| `s34d` | 06:09:40Z | `s34d-control-minimal`              | control          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                     | `340f2f996aa63965` | clean-open                  | valid                                      | valid                                                                                                                                                |

<details><summary>Raw records, session 34</summary>

```jsonl
{"run": "s34a", "name": "s34a-control-minimal", "sha256": "478df25aa65036422ba1ff97c2f62f2fa5d862e73ed1cf45d7a10693faf8efe7", "observedAt": "2026-10-25T06:05:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s34a", "name": "mce-fallback-main-malformed-doc", "sha256": "5de3536778f4a45ce7aa7d790725e31e6cc5b5193f709fffca031bd4680cc8f7", "observedAt": "2026-10-25T06:04:21.999Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00003__wfv__mce-fallback-main-malformed-doc.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34a", "name": "direct-main-malformed-doc", "sha256": "5614b876b20a59da5b1bce7aebf782c1f94fe1df1312c71c6507500e841e2ade", "observedAt": "2026-10-25T06:04:05.865Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__direct-main-malformed-doc.docx; refusing to guess", "dialogs": ["\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter.", "'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver"]}
{"run": "s34a", "name": "mce-fallback-main-zerobyte-rels", "sha256": "79ee3843a83ef05cd8b4c1ec8ca2a2a2d40a23de83831049b3925d0fcdeaf13f", "observedAt": "2026-10-25T06:04:26.370Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__mce-fallback-main-zerobyte-rels.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__mce-fallback-main-zerobyte-rels.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34a", "name": "direct-main-zerobyte-rels", "sha256": "c4f0d4f9105990792c2e769df5c74d0d8b1f7ec35f128dd800c9c4b5543f19a0", "observedAt": "2026-10-25T06:04:11.461Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__direct-main-zerobyte-rels.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__direct-main-zerobyte-rels.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34a", "name": "mce-fallback-split-duplicate-id", "sha256": "e3635fd614c69c58252ef8dc8a056e7e6370f484732f882fb39a5d79fb978702", "observedAt": "2026-10-25T06:04:36.532Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__mce-fallback-split-duplicate-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__mce-fallback-split-duplicate-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34a", "name": "direct-duplicate-id", "sha256": "5d4151891441e71bcfb059a5f0030481a8cf7271d858de3a66561a613c072d55", "observedAt": "2026-10-25T06:03:10.531Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__direct-duplicate-id.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__direct-duplicate-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__direct-duplicate-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34a", "name": "s34a-control-minimal-end", "sha256": "39a5184664dcf46feced009d5fbc12807f7800a5eee395108534b221fe546759", "observedAt": "2026-10-25T06:05:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s34b", "name": "s34b-control-minimal", "sha256": "39a5184664dcf46feced009d5fbc12807f7800a5eee395108534b221fe546759", "observedAt": "2026-10-25T06:08:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s34b", "name": "mce-fallback-malformed-coreprops", "sha256": "e371880140b48156a9c87644968628508ec3c682dce46e89b0e8214620b30b5f", "observedAt": "2026-10-25T06:07:21.647Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00003__wfv__mce-fallback-malformed-coreprops.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s34b", "name": "direct-malformed-coreprops", "sha256": "f7930cf3cc8f6f7b2e7913f053f9f721a0a0b3ba1e9fe9692ee56deccef5db00", "observedAt": "2026-10-25T06:06:23.924Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__direct-malformed-coreprops.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__direct-malformed-coreprops.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__direct-malformed-coreprops.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34b", "name": "mce-fallback-footer-header-ct", "sha256": "0da480e77533fc650883fea0180895f6495a6953c94646348e85f5139c9770a0", "observedAt": "2026-10-25T06:07:11.503Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__mce-fallback-footer-header-ct.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__mce-fallback-footer-header-ct.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__mce-fallback-footer-header-ct.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s34b", "name": "direct-footer-header-ct", "sha256": "5b931e0c8dd4fd2e5c574ee45660528a27a52a458558519db1a9fb060ad1cb7d", "observedAt": "2026-10-25T06:05:30.970Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__direct-footer-header-ct.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__direct-footer-header-ct.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__direct-footer-header-ct.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34b", "name": "mce-rels-root-mustunderstand", "sha256": "c27cdf562eda521047daa8837452c1f317d79201743e414e326d20a312eaee8c", "observedAt": "2026-10-25T06:08:28+00:00", "outcome": "other", "item": "failed", "error": "Word crashed on it in 2 passes: Microsoft Word got an error: Connection is invalid.", "dialogs": []}
{"run": "s34b", "name": "mce-rels-choice-undeclared-prefix", "sha256": "fe8c495cf8d607d3a471116852f000bb7ffc30ecbd866d2d78eb61c0faa93d50", "observedAt": "2026-10-25T06:08:25.192Z", "outcome": "repair-warning", "item": "failed", "error": "Word crashed on it in 2 passes: Microsoft Word got an error: Connection is invalid.", "dialogs": ["'Word found unreadable content in 00004__wfv__mce-rels-choice-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'"]}
{"run": "s34b", "name": "s34b-control-minimal-end", "sha256": "a9d7b233ab8369294f489aad08dcf1ab6523d73562e4fec47fbcf06556093bd6", "observedAt": "2026-10-25T06:08:28+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s34c", "name": "mce-rels-root-mustunderstand", "sha256": "84f47433da625890a859ebf325b8ac5491084099639218393bed9db03819b0e4", "observedAt": "2026-10-25T06:09:15.927Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__mce-rels-root-mustunderstand.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__mce-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__mce-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34c", "name": "s34c-control-minimal", "sha256": "340f2f996aa63965aa62581a1a14a94816ca9ac4e31e46eadeaae268485658aa", "observedAt": "2026-10-25T06:09:20+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s34d", "name": "mce-rels-choice-undeclared-prefix", "sha256": "961d1b7b77cd7379bf3ec017e94fe90b119a1b16da2972ae79bc6f93442dfcf3", "observedAt": "2026-10-25T06:09:37.741Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__mce-rels-choice-undeclared-prefix.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__mce-rels-choice-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__mce-rels-choice-undeclared-prefix.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s34d", "name": "s34d-control-minimal", "sha256": "340f2f996aa63965aa62581a1a14a94816ca9ac4e31e46eadeaae268485658aa", "observedAt": "2026-10-25T06:09:40+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 35: 06:25Z–06:28Z on 2026-10-25, validator columns at 9ac8d583

The adversarial review of layer 130 (empryo devin/swe-2), suspected findings 5–8, with two clean controls in every chunk. The driver opens each chunk's files in name order, so the controls were queued first in `s35a`, 5th and 6th of 8 in `s35b`, and last in `s35c` ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). In `s35b` Word stalled on four specimens, and the driver reopened them in later passes, after the controls ([#672](https://github.com/jandira-tech/docx-validate/issues/672)).

| Run    | Observed  | Specimen                              | Issue                                       | Shape                                                                                                                                                                                                                                                                                           | SHA-256 (first 16) | Word           | word-valid at 9ac8d583                     | strict at 9ac8d583                                                               |
| ------ | --------- | ------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------ | -------------------------------------------------------------------------------- |
| `s35a` | 06:25:38Z | `s35a-control-minimal`                | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `f930e0867aa34565` | clean-open     | valid                                      | valid                                                                            |
| `s35a` | 06:25:38Z | `unread-xtra-rs-id-no-sidecar`        | #638 (review 130 finding 5)                 | `MINIMAL_PARTS` plus an unreferenced `word/xtra.xml`, `<x:root xmlns:x="urn:x">` holding `<x:e rs:id="rId9"/>` (ISO Strict relationships namespace), no `.rels`                                                                                                                                 | `37b4859edfdcc272` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s35a` | 06:25:38Z | `unread-xtra-r-id-no-sidecar`         | #638 twin (Transitional)                    | the same with a Transitional `r:id`                                                                                                                                                                                                                                                             | `1a1147e1cecc8e33` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s35a` | 06:25:38Z | `unread-app-props-rs-id-no-sidecar`   | #638 (review 130 finding 5)                 | `MINIMAL_PARTS` plus `docProps/app.xml` with its Override and no relationship, `<Application rs:id="rId9">`, no `.rels`                                                                                                                                                                         | `86dcb93528a77cbc` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s35a` | 06:25:38Z | `unreached-glossary-rs-id-no-sidecar` | #638 (review 130 finding 5)                 | `MINIMAL_PARTS` plus an ISO Strict `word/glossary/document.xml` with its Override and no `glossaryDocument` relationship, a `w:footerReference rs:id="rId9"` in a `w:docPartBody` `w:sectPr`, no `.rels`                                                                                        | `ddf82ef1c9eb6f42` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `rels-unreferenced`                             |
| `s35a` | 06:25:38Z | `styles-rs-id-no-sidecar`             | #638 (review 130 finding 5)                 | `MINIMAL_PARTS` with `rs:id="rId9"` on the first `w:name` of `word/styles.xml`, which has no `.rels`                                                                                                                                                                                            | `cb8546802b5c65d4` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary`                      |
| `s35a` | 06:25:38Z | `s35a-control-minimal-end`            | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `5d9f08c1efc1ee32` | clean-open     | valid                                      | valid                                                                            |
| `s35b` | 06:26:53Z | `s35b-control-minimal`                | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `5d9f08c1efc1ee32` | clean-open     | valid                                      | valid                                                                            |
| `s35b` | 06:26:53Z | `mce-unselected-rs-embed-no-sidecar`  | #638 (review 130 finding 6)                 | `MINIMAL_PARTS` without `word/_rels/document.xml.rels`, the body holding `<mc:AlternateContent><mc:Choice Requires="foo"><w:p><w:r><w:drawing><a:blip rs:embed="rId9"/></w:drawing></w:r></w:p></mc:Choice><mc:Fallback/></mc:AlternateContent>` (`foo` = `urn:foo`) before the body `w:sectPr` | `c0899813960b1eec` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `paraid-missing-element`, `rels-missing-sidecar`, `rels-unreferenced`   |
| `s35b` | 06:26:53Z | `mce-unselected-r-embed-no-sidecar`   | #638 twin (Transitional)                    | the same with a Transitional `r:embed`                                                                                                                                                                                                                                                          | `e5af8b5f89d47fca` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `paraid-missing-element`, `rels-missing-sidecar`, `rels-unreferenced`   |
| `s35b` | 06:26:20Z | `sectprchange-rs-id-no-sidecar`       | review 130 finding 6 (calibration for #638) | `MINIMAL_PARTS` without `word/_rels/document.xml.rels`, a `w:footerReference w:type="default" rs:id="rId9"` inside `w:sectPrChange/w:sectPr` at the end of the body `w:sectPr`                                                                                                                  | `24bf7cf6dd8fb77d` | repair-warning | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `rels-unreferenced`, `xsd-error`, `xsd-summary` |
| `s35b` | 06:26:15Z | `sectprchange-footerref-no-id`        | review 130 finding 7 (#623)                 | `MINIMAL_PARTS` with `<w:footerReference w:type="default"/>` (no id) inside `w:sectPrChange/w:sectPr` at the end of the body `w:sectPr`                                                                                                                                                         | `df3d9ae1815f280d` | open-error     | invalid: `word-header-footer-relationship` | invalid: `word-header-footer-relationship`, `xsd-error`, `xsd-summary`           |
| `s35b` | 06:26:05Z | `body-child-footerref-no-id`          | review 130 finding 7 (#623)                 | `MINIMAL_PARTS` with `<w:footerReference w:type="default"/>` (no id) as a direct `w:body` child before the body `w:sectPr`                                                                                                                                                                      | `43d67a73dc2e5ab8` | open-error     | invalid: `word-header-footer-relationship` | invalid: `word-header-footer-relationship`, `xsd-error`, `xsd-summary`           |
| `s35b` | 06:26:10Z | `ppr-sectpr-footerref-no-id`          | review 130 finding 7 (#623)                 | `MINIMAL_PARTS` with `<w:footerReference w:type="default"/>` (no id) in a paragraph-level `w:pPr/w:sectPr`                                                                                                                                                                                      | `e54fb5744158b43e` | open-error     | invalid: `word-header-footer-relationship` | invalid: `word-header-footer-relationship`, `xsd-error`, `xsd-summary`           |
| `s35b` | 06:26:53Z | `s35b-control-minimal-end`            | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `4293acd4ef77952a` | clean-open     | valid                                      | valid                                                                            |
| `s35c` | 06:28:26Z | `s35c-control-minimal`                | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `4293acd4ef77952a` | clean-open     | valid                                      | valid                                                                            |
| `s35c` | 06:27:22Z | `footerref-rid-empty-x-id`            | review 130 finding 8 (#623)                 | `MINIMAL_PARTS` with a body `w:sectPr` `<w:footerReference w:type="default" r:id="" x:id="rId9"/>` (`x` = `urn:x`)                                                                                                                                                                              | `400ef042eb6c180a` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `word-header-footer-relationship`, `xsd-error`, `xsd-summary`           |
| `s35c` | 06:28:23Z | `footerref-rid-whitespace`            | review 130 finding 8 (#623)                 | `MINIMAL_PARTS` with a body `w:sectPr` `<w:footerReference w:type="default" r:id=" "/>`                                                                                                                                                                                                         | `a41c3a3f6cc36a7a` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `word-header-footer-relationship`                                       |
| `s35c` | 06:28:26Z | `s35c-control-minimal-end`            | control                                     | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                 | `4293acd4ef77952a` | clean-open     | valid                                      | valid                                                                            |

<details><summary>Raw records, session 35</summary>

```jsonl
{"run": "s35a", "name": "s35a-control-minimal", "sha256": "f930e0867aa345651dab60b1c9527092cda970897ec7bc5eef195a782362854f", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "unread-xtra-rs-id-no-sidecar", "sha256": "37b4859edfdcc27201b4592b252bf27e6f22ab8e5f21cfdf175dfcd0045ca0c7", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "unread-xtra-r-id-no-sidecar", "sha256": "1a1147e1cecc8e33c763f5f2c6a8ee78f88b76ea7770260bd204464b7aa21ca8", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "unread-app-props-rs-id-no-sidecar", "sha256": "86dcb93528a77cbc965b5c8ad6b599c30e58b159951842619af93a8f1c0dd304", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "unreached-glossary-rs-id-no-sidecar", "sha256": "ddf82ef1c9eb6f427408acce89f37a3a2aa16d7d4325b190384e55c7096503dd", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "styles-rs-id-no-sidecar", "sha256": "cb8546802b5c65d4ca6e6cb81c35a4e47e270ae6eea91afd1c6800d6e9e58d0c", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35a", "name": "s35a-control-minimal-end", "sha256": "5d9f08c1efc1ee3210619b045eb5757fe847fbc56867276e1ea3d7289b1653a1", "observedAt": "2026-10-25T06:25:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35b", "name": "s35b-control-minimal", "sha256": "5d9f08c1efc1ee3210619b045eb5757fe847fbc56867276e1ea3d7289b1653a1", "observedAt": "2026-10-25T06:26:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35b", "name": "mce-unselected-rs-embed-no-sidecar", "sha256": "c0899813960b1eecf214c8790d5f4dafddc8f82bebc81699d8d2f8d2145098fa", "observedAt": "2026-10-25T06:26:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35b", "name": "mce-unselected-r-embed-no-sidecar", "sha256": "e5af8b5f89d47fca97b132a863da675b379f6660b69788cef39911aa72a5eff2", "observedAt": "2026-10-25T06:26:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35b", "name": "sectprchange-rs-id-no-sidecar", "sha256": "24bf7cf6dd8fb77da2f675b65febfab14b8107a303e7a5131c63d62052911e51", "observedAt": "2026-10-25T06:26:20.054Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__sectprchange-rs-id-no-sidecar.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00007__wfv__sectprchange-rs-id-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00007__wfv__sectprchange-rs-id-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s35b", "name": "sectprchange-footerref-no-id", "sha256": "df3d9ae1815f280d0dd6276765137d24c3129d466695c796139ab3fc1c5bfbda", "observedAt": "2026-10-25T06:26:15.582Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00006__wfv__sectprchange-footerref-no-id.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s35b", "name": "body-child-footerref-no-id", "sha256": "43d67a73dc2e5ab81169ceff9131ff5f11b0a90f72f6f99f4afbdc5f55a9346d", "observedAt": "2026-10-25T06:26:05.853Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00000__wfv__body-child-footerref-no-id.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s35b", "name": "ppr-sectpr-footerref-no-id", "sha256": "e54fb5744158b43e575c1eefaafa506a84c34068838f207fdb5d15e9c38c1268", "observedAt": "2026-10-25T06:26:10.584Z", "outcome": "open-error", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00003__wfv__ppr-sectpr-footerref-no-id.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s35b", "name": "s35b-control-minimal-end", "sha256": "4293acd4ef77952ab9eb2536a353698b02ee24307df73d76ad60129f0abde8d4", "observedAt": "2026-10-25T06:26:53+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35c", "name": "s35c-control-minimal", "sha256": "4293acd4ef77952ab9eb2536a353698b02ee24307df73d76ad60129f0abde8d4", "observedAt": "2026-10-25T06:28:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s35c", "name": "footerref-rid-empty-x-id", "sha256": "400ef042eb6c180a829d333342d99e1555ecd9711b7c29aeaffaa523f4ff9277", "observedAt": "2026-10-25T06:27:22.887Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__footerref-rid-empty-x-id.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__footerref-rid-empty-x-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__footerref-rid-empty-x-id.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s35c", "name": "footerref-rid-whitespace", "sha256": "a41c3a3f6cc36a7ad8af8d6752b1d0f260607b5a210a7971d2ac8ff7cfe6021c", "observedAt": "2026-10-25T06:28:23.935Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__footerref-rid-whitespace.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00001__wfv__footerref-rid-whitespace.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__footerref-rid-whitespace.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s35c", "name": "s35c-control-minimal-end", "sha256": "4293acd4ef77952ab9eb2536a353698b02ee24307df73d76ad60129f0abde8d4", "observedAt": "2026-10-25T06:28:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 36: 07:29Z–07:37Z on 2026-10-25, validator columns at dd5a3da2

The adversarial reviews of #636 (empryo devin/swe-2; suspected findings S1–S6) and of layer 131 (pi glm-5.3; suspected findings S2–S4 and the shape of proven finding P1, #640), the #638 boundary, and the scope questions their results left (`s36d`, `s36e`), with two clean controls in every chunk. The driver opens each chunk's files in name order, so the controls ran 4th and 5th of 6 in `s36a`, last in `s36b` and `s36c`, and 5th and 6th of 7 in `s36d` and `s36e` ([#671](https://github.com/jandira-tech/docx-validate/issues/671)).

| Run    | Observed  | Specimen                                           | Issue                            | Shape                                                                                                                                                                                                                                                                             | SHA-256 (first 16) | Word           | word-valid at dd5a3da2                     | strict at dd5a3da2                                                                                                                  |
| ------ | --------- | -------------------------------------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `s36a` | 07:30:32Z | `s36a-control-minimal`                             | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `022302d84499b758` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36a` | 07:29:43Z | `docrels-mc-malformed-sibling`                     | #636 (`s34d` discriminator)      | `MINIMAL_PARTS` with the malformed sibling (`<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent>`, `xmlns:mc` on the root, `nope` undeclared) appended to `word/_rels/document.xml.rels`; no relationship is hidden                             | `75da5598bb7fff6c` | repair-warning | invalid: `mce-malformed`                   | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                                                                  |
| `s36a` | 07:30:30Z | `pkgrels-mc-malformed-sibling`                     | #644 (review of #636, S3)        | `MINIMAL_PARTS` with the same sibling appended to `_rels/.rels`                                                                                                                                                                                                                   | `85073324339bf6d4` | repair-warning | valid                                      | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `xsd-error`, `xsd-summary`                                      |
| `s36a` | 07:30:25Z | `glossary-rels-mc-malformed-sibling`               | #644 (review of #636, S1)        | session 26's glossary footer package (`glossaryStoryReferenceParts`, `word/glossary/footer9.xml`) with the same sibling appended to `word/glossary/_rels/document.xml.rels`                                                                                                       | `0a2b52b74beed095` | repair-warning | valid                                      | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `paraid-missing-element`                                        |
| `s36a` | 07:30:32Z | `stray-docrels-mc-malformed-sibling`               | #644 (review of #636, S2)        | `MINIMAL_PARTS` with the main document moved to `word/doc2.xml` (package relationship, Override and `.rels` renamed with it), the old `word/document.xml` left unreached, and the same sibling appended to the stray `word/_rels/document.xml.rels`                               | `a33e6f975e124d2d` | clean-open     | invalid: `mce-malformed`                   | invalid: `ct-undeclared-part`, `mce-malformed`, `opc-relationships-markup-compatibility`, `rels-unreferenced`                       |
| `s36a` | 07:30:32Z | `s36a-control-minimal-end`                         | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `a1f824faff732b09` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36b` | 07:31:26Z | `s36b-control-minimal`                             | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `a1f824faff732b09` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36b` | 07:31:24Z | `pkgrels-relationship-mustunderstand`              | review of #636, S4               | `MINIMAL_PARTS` with `mc:MustUnderstand="foo"` (`foo` = `urn:foo`) on the `officeDocument` `Relationship` of `_rels/.rels`                                                                                                                                                        | `49d528598f9b6d76` | repair-warning | invalid: `mce-must-understand`             | invalid: `mce-must-understand`, `xsd-error`, `xsd-summary`                                                                          |
| `s36b` | 07:31:20Z | `docrels-root-mustunderstand`                      | #644 (review of #636, S6)        | `MINIMAL_PARTS` with `mc:MustUnderstand="foo"` (`foo` = `urn:foo`) on the `word/_rels/document.xml.rels` root                                                                                                                                                                     | `e9d26b2a780f31bf` | repair-warning | valid                                      | invalid: `mce-must-understand`                                                                                                      |
| `s36b` | 07:31:10Z | `docrels-mc-fallback-only`                         | review of #636, S5               | `MINIMAL_PARTS` with the styles relationship of `word/_rels/document.xml.rels` inside `<mc:AlternateContent><mc:Fallback>…</mc:Fallback></mc:AlternateContent>` (no Choice)                                                                                                       | `27c3b9821508e2fc` | repair-warning | invalid: `mce-malformed`                   | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                                                                  |
| `s36b` | 07:31:16Z | `docrels-mc-foreign-branch`                        | review of #636, S5               | the same with `<foo:bar/>` (`foo` = `urn:foo`) before the Fallback                                                                                                                                                                                                                | `de8e2c363459fc3b` | repair-warning | invalid: `mce-malformed`                   | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                                                                  |
| `s36b` | 07:31:26Z | `chart-outside-word-related-no-sidecar`            | #645 (#638 boundary)             | `MINIMAL_PARTS` plus `charts/chart1.xml` (a bare `c:plotArea` and `<c:externalData r:id="rId1"/>`, Override, no `.rels`), related from `word/_rels/document.xml.rels` as `rId9` (`../charts/chart1.xml`), referenced by nothing                                                   | `e2be756aea7514e1` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary`                                                                         |
| `s36b` | 07:31:26Z | `chart-word-related-no-sidecar`                    | #645 (#638 boundary)             | the same at `word/charts/chart1.xml`                                                                                                                                                                                                                                              | `11d615263f710d6a` | clean-open     | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary`                                                                         |
| `s36b` | 07:31:26Z | `s36b-control-minimal-end`                         | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `45bd39785c53b9f5` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36c` | 07:32:22Z | `s36c-control-minimal`                             | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `351c62a8d7d9c59c` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36c` | 07:32:22Z | `pkgrels-root-ac-fallback-relationships`           | #646 (review of layer 131, S3)   | `MINIMAL_PARTS` with `_rels/.rels` holding `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>`, its `Relationships` element, `</mc:Fallback></mc:AlternateContent>`                                                                                                   | `95a33fb1bbc883d4` | clean-open     | invalid: `opc-relationships-structure`     | invalid: `opc-relationships-structure`, `xsd-error`, `xsd-summary`                                                                  |
| `s36c` | 07:32:20Z | `pkgrels-root-ac-fallback-two-relationships`       | #640 (review of layer 131, P1)   | the same with two bare `Relationship` elements in the Fallback: `rId1` `officeDocument` and `rId2` `styles` (`word/styles.xml`)                                                                                                                                                   | `0714243c6ba4cfb7` | repair-warning | throws `HierarchyRequestError`             | throws `HierarchyRequestError`                                                                                                      |
| `s36c` | 07:32:22Z | `docrels-processcontent-wrapper-footer`            | review of layer 131, S2          | session 26's footer package (`storyReferenceParts`, footer relationship `rIdX`) with the footer relationship inside `<x:Wrap>` and `mc:Ignorable="x" mc:ProcessContent="x:Wrap"` (`x` = `urn:x`) on the `word/_rels/document.xml.rels` root                                       | `dada260f62ae586b` | clean-open     | valid                                      | invalid: `opc-relationships-markup-compatibility`, `paraid-missing-element`                                                         |
| `s36c` | 07:32:15Z | `docrels-ignorable-wrapper-footer`                 | review of layer 131, S2 (mirror) | the same without `mc:ProcessContent`                                                                                                                                                                                                                                              | `f0c8fd083078fe42` | repair-warning | invalid: `word-header-footer-relationship` | invalid: `opc-relationships-markup-compatibility`, `paraid-missing-element`, `rels-unreferenced`, `word-header-footer-relationship` |
| `s36c` | 07:32:22Z | `pkgrels-dup-id-choice-fallback`                   | review of layer 131, S4          | `MINIMAL_PARTS` with `_rels/.rels` holding, after the direct `rId1`, an `mc:AlternateContent` whose `mc:Choice Requires="w14"` and `mc:Fallback` each hold the same `styles` `rId2`                                                                                               | `63d7de53d48c9dd4` | clean-open     | valid                                      | invalid: `opc-relationships-markup-compatibility`, `xsd-error`, `xsd-summary`                                                       |
| `s36c` | 07:32:22Z | `s36c-control-minimal-end`                         | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `351c62a8d7d9c59c` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36d` | 07:35:32Z | `s36d-control-minimal`                             | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `aef19e280a918119` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36d` | 07:35:32Z | `chart-word-referenced-no-externaldata-no-sidecar` | control for `s36d`               | `MINIMAL_PARTS` plus `word/charts/chart1.xml` (a clustered bar chart without `c:externalData`, Override, no `.rels`), related from `word/_rels/document.xml.rels` as `rId9`, referenced by an inline `wp:inline` drawing with `<c:chart r:id="rId9"/>` before the body `w:sectPr` | `3b88238c2ce8ac83` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36d` | 07:35:28Z | `chart-word-referenced-no-sidecar`                 | #645 (#638 boundary)             | the same chart with `<c:externalData r:id="rId1"/>`                                                                                                                                                                                                                               | `195db897862fd2ff` | repair-warning | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`                                                                                                     |
| `s36d` | 07:35:18Z | `chart-outside-word-referenced-no-sidecar`         | #645 (#638 boundary)             | the same at `charts/chart1.xml` (`../charts/chart1.xml`)                                                                                                                                                                                                                          | `13f0ff6dbe2ab131` | repair-warning | invalid: `rels-missing-sidecar`            | invalid: `rels-missing-sidecar`                                                                                                     |
| `s36d` | 07:35:32Z | `styles-rels-mc-malformed-sibling`                 | #644 (scope)                     | `MINIMAL_PARTS` plus `word/_rels/styles.xml.rels`: an empty `Relationships` holding only the malformed sibling (`<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent>`, `xmlns:mc` on the root, `nope` undeclared)                               | `3361b0be75c7262a` | clean-open     | valid                                      | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                                                                  |
| `s36d` | 07:35:32Z | `footer-rels-mc-malformed-sibling`                 | #644 (scope)                     | session 26's footer package (`storyReferenceParts`, footer relationship `rIdX`) plus `word/_rels/footer1.xml.rels`, the same                                                                                                                                                      | `5c239d5dfb4d7acb` | clean-open     | valid                                      | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `paraid-missing-element`                                        |
| `s36d` | 07:35:32Z | `s36d-control-minimal-end`                         | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `aef19e280a918119` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36e` | 07:37:12Z | `s36e-control-minimal`                             | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `8c0c51103506e611` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36e` | 07:37:12Z | `renamed-main-control`                             | control for `s36e`               | `MINIMAL_PARTS` with the main document moved to `word/doc2.xml` (package relationship, Override and `.rels` renamed with it)                                                                                                                                                      | `23db2d38bffe779d` | clean-open     | valid                                      | valid                                                                                                                               |
| `s36e` | 07:36:58Z | `renamed-main-rels-mc-malformed-sibling`           | #644 (scope)                     | that package with the malformed sibling (`<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent>`, `xmlns:mc` on the root, `nope` undeclared) appended to `word/_rels/doc2.xml.rels`                                                               | `9decdcc472dbbd61` | repair-warning | valid                                      | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                                                                  |
| `s36e` | 07:37:04Z | `renamed-main-rels-root-mustunderstand`            | #644 (scope)                     | that package with `mc:MustUnderstand="foo"` (`foo` = `urn:foo`) on the `word/_rels/doc2.xml.rels` root                                                                                                                                                                            | `76c84b400689134c` | repair-warning | valid                                      | invalid: `mce-must-understand`                                                                                                      |
| `s36e` | 07:37:12Z | `stray-docrels-root-mustunderstand`                | #644 (scope)                     | that package plus the unreached `word/document.xml` and a stray `word/_rels/document.xml.rels` whose root carries `mc:MustUnderstand="foo"` (`foo` = `urn:foo`)                                                                                                                   | `6ef6639f1796cfea` | clean-open     | valid                                      | invalid: `ct-undeclared-part`, `mce-must-understand`, `rels-unreferenced`                                                           |
| `s36e` | 07:36:45Z | `glossary-rels-root-mustunderstand`                | #644 (scope)                     | session 26's glossary footer package (`glossaryStoryReferenceParts`, `word/glossary/footer9.xml`) with `mc:MustUnderstand="foo"` (`foo` = `urn:foo`) on the `word/glossary/_rels/document.xml.rels` root                                                                          | `ef76dde4a80099fe` | repair-warning | valid                                      | invalid: `mce-must-understand`, `paraid-missing-element`                                                                            |
| `s36e` | 07:37:12Z | `s36e-control-minimal-end`                         | control                          | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                   | `8c0c51103506e611` | clean-open     | valid                                      | valid                                                                                                                               |

<details><summary>Raw records, session 36</summary>

```jsonl
{"run": "s36a", "name": "s36a-control-minimal", "sha256": "022302d84499b75870da2329b887c7fdffc8d181950030400dff8465b035a918", "observedAt": "2026-10-25T07:30:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36a", "name": "docrels-mc-malformed-sibling", "sha256": "75da5598bb7fff6c188d8543e636359dda4e822c429d56db8ce94385a66a433a", "observedAt": "2026-10-25T07:29:43.608Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__docrels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__docrels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s36a", "name": "pkgrels-mc-malformed-sibling", "sha256": "85073324339bf6d4723c3af63bea492ebb6bb522e18afb4ccdc025eeb2a3dead", "observedAt": "2026-10-25T07:30:30.689Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["\"Word found unreadable content in 00002__wfv__pkgrels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36a", "name": "glossary-rels-mc-malformed-sibling", "sha256": "0a2b52b74beed095eb6d4c469868c60d8f5590522b8e4d40bcc4c519bc8d33fd", "observedAt": "2026-10-25T07:30:25.365Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00001__wfv__glossary-rels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__glossary-rels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s36a", "name": "stray-docrels-mc-malformed-sibling", "sha256": "a33e6f975e124d2d0743253be84f5cc373814243fda4a479d79199e4744bc4a8", "observedAt": "2026-10-25T07:30:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36a", "name": "s36a-control-minimal-end", "sha256": "a1f824faff732b0956184a1086a724b4654147a31563bb045d41a0fbcc3a2782", "observedAt": "2026-10-25T07:30:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36b", "name": "s36b-control-minimal", "sha256": "a1f824faff732b0956184a1086a724b4654147a31563bb045d41a0fbcc3a2782", "observedAt": "2026-10-25T07:31:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36b", "name": "pkgrels-relationship-mustunderstand", "sha256": "49d528598f9b6d76fbe6b6b3fd873bbcdb2f1ce87e7c63b26fe6c2b9ac509e37", "observedAt": "2026-10-25T07:31:24.809Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00005__wfv__pkgrels-relationship-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__pkgrels-relationship-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36b", "name": "docrels-root-mustunderstand", "sha256": "e9d26b2a780f31bfe950a28457b20197dfa0594fac983445c22a9f8746ba8c68", "observedAt": "2026-10-25T07:31:20.577Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__docrels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__docrels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36b", "name": "docrels-mc-fallback-only", "sha256": "27c3b9821508e2fcf18c575704f9d48d17040e3d68938dca62caf5bca3f7a426", "observedAt": "2026-10-25T07:31:10.906Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__docrels-mc-fallback-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__docrels-mc-fallback-only.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36b", "name": "docrels-mc-foreign-branch", "sha256": "de8e2c363459fc3b8fd6bd58db74a2c8b16aff2e34be21880e90b5afe936e60b", "observedAt": "2026-10-25T07:31:16.355Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__docrels-mc-foreign-branch.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__docrels-mc-foreign-branch.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36b", "name": "chart-outside-word-related-no-sidecar", "sha256": "e2be756aea7514e1ad978be69883faf5e626d4578920f1d77452c6ea27bde4e1", "observedAt": "2026-10-25T07:31:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36b", "name": "chart-word-related-no-sidecar", "sha256": "11d615263f710d6a932df1b5ca1ab9de0cc231fb5f56da80e2e167451146586a", "observedAt": "2026-10-25T07:31:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36b", "name": "s36b-control-minimal-end", "sha256": "45bd39785c53b9f50a42c1a0ba2ae1161ffc78edceefe9b16c1677dbe74fed31", "observedAt": "2026-10-25T07:31:26+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36c", "name": "s36c-control-minimal", "sha256": "351c62a8d7d9c59c08c95bf1639a9b281e1f4f04f1b58a71f6553171baf7bc65", "observedAt": "2026-10-25T07:32:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36c", "name": "pkgrels-root-ac-fallback-relationships", "sha256": "95a33fb1bbc883d4d6c091a57869002826a1341301e5c4b7d5f0f952a0ff363b", "observedAt": "2026-10-25T07:32:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36c", "name": "pkgrels-root-ac-fallback-two-relationships", "sha256": "0714243c6ba4cfb79f91ec4dce297589d5ccd1433a27037a16241be6c819df98", "observedAt": "2026-10-25T07:32:20.384Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00004__wfv__pkgrels-root-ac-fallback-two-relationships.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__pkgrels-root-ac-fallback-two-relationships.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36c", "name": "docrels-processcontent-wrapper-footer", "sha256": "dada260f62ae586bb30621ace7435957c218a8db422a87daaef6931a00dab752", "observedAt": "2026-10-25T07:32:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36c", "name": "docrels-ignorable-wrapper-footer", "sha256": "f0c8fd083078fe425a9ba0418919b7ef35ce247e92b08113d8536fbad9eff83e", "observedAt": "2026-10-25T07:32:15.977Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__docrels-ignorable-wrapper-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__docrels-ignorable-wrapper-footer.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36c", "name": "pkgrels-dup-id-choice-fallback", "sha256": "63d7de53d48c9dd489e03937d6ee9b4c1ac7337d17bfa1dec4c670dffffd155e", "observedAt": "2026-10-25T07:32:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36c", "name": "s36c-control-minimal-end", "sha256": "351c62a8d7d9c59c08c95bf1639a9b281e1f4f04f1b58a71f6553171baf7bc65", "observedAt": "2026-10-25T07:32:22+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36d", "name": "s36d-control-minimal", "sha256": "aef19e280a918119003ade3f70ad4bf739a3b4b1e3fd7a29166c147ad8e46a2b", "observedAt": "2026-10-25T07:35:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36d", "name": "chart-word-referenced-no-externaldata-no-sidecar", "sha256": "3b88238c2ce8ac83bdda8ad88fe9eafc040af9a0c5942f2e20aeb1d7dd568d97", "observedAt": "2026-10-25T07:35:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36d", "name": "chart-word-referenced-no-sidecar", "sha256": "195db897862fd2ffd29a3c17cf0dcc10270eaf8872279103adfeedad3a32f676", "observedAt": "2026-10-25T07:35:28.468Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__chart-word-referenced-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__chart-word-referenced-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36d", "name": "chart-outside-word-referenced-no-sidecar", "sha256": "13f0ff6dbe2ab131259bd0b5b8204916c1cb9956a2799e8e8d676283bf0d0ad3", "observedAt": "2026-10-25T07:35:18.045Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__chart-outside-word-referenced-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__chart-outside-word-referenced-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36d", "name": "styles-rels-mc-malformed-sibling", "sha256": "3361b0be75c7262a28c5739101709c0305377b83c70dc95fc14a5ddd3ef2e5a9", "observedAt": "2026-10-25T07:35:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36d", "name": "footer-rels-mc-malformed-sibling", "sha256": "5c239d5dfb4d7acb959beb3ccb990cffa252d17e965f203bc6a7bf26bdeaf69f", "observedAt": "2026-10-25T07:35:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36d", "name": "s36d-control-minimal-end", "sha256": "aef19e280a918119003ade3f70ad4bf739a3b4b1e3fd7a29166c147ad8e46a2b", "observedAt": "2026-10-25T07:35:32+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36e", "name": "s36e-control-minimal", "sha256": "8c0c51103506e6115e14c5d37fbffd8288a414dd31ca7599b29998a06b784087", "observedAt": "2026-10-25T07:37:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36e", "name": "renamed-main-control", "sha256": "23db2d38bffe779d7d92459af1a283245d7025ca358324b7802425b22d9d50c3", "observedAt": "2026-10-25T07:37:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36e", "name": "renamed-main-rels-mc-malformed-sibling", "sha256": "9decdcc472dbbd616838bee5a47fb27b392a4128109844052a161581d3843de5", "observedAt": "2026-10-25T07:36:58.310Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00002__wfv__renamed-main-rels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__renamed-main-rels-mc-malformed-sibling.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36e", "name": "renamed-main-rels-root-mustunderstand", "sha256": "76c84b400689134c2523f2d94be17193aff9c154a9290f310c392f04c0f52f1c", "observedAt": "2026-10-25T07:37:04.095Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00003__wfv__renamed-main-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__renamed-main-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36e", "name": "stray-docrels-root-mustunderstand", "sha256": "6ef6639f1796cfeab38a363a8d828d5a0e1715020d369f619969df0d6f7ba9f9", "observedAt": "2026-10-25T07:37:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s36e", "name": "glossary-rels-root-mustunderstand", "sha256": "ef76dde4a80099fe4982f0caa9520b6e5f9204bb59efb15940d99f20d10837a7", "observedAt": "2026-10-25T07:36:45.600Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it", "dialogs": ["'Word found unreadable content in 00000__wfv__glossary-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__glossary-rels-root-mustunderstand.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s36e", "name": "s36e-control-minimal-end", "sha256": "8c0c51103506e6115e14c5d37fbffd8288a414dd31ca7599b29998a06b784087", "observedAt": "2026-10-25T07:37:12+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 37: 08:04Z–08:15Z on 2026-10-25, validator columns at ab2e324f, 7cb4041e and 76bb5622

The sidecars #644 left unobserved (`s37a`) and the two boundary shapes #645's fix derived without evidence (`s37b`), with two clean controls in every chunk. The driver opens each chunk's files in name order, so the controls ran 4th and 5th of 8 in `s37a` and last in `s37b` ([#671](https://github.com/jandira-tech/docx-validate/issues/671)).

| Run    | Observed  | Specimen                                        | Issue                           | Shape                                                                                                                                                                                                                                                                                                                                               | SHA-256 (first 16) | Word           | word-valid at ab2e324f                 | word-valid at 7cb4041e          | word-valid at 76bb5622          | strict at 7cb4041e                                                                           |
| ------ | --------- | ----------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------------------------------- | ------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------- |
| `s37a` | 08:04:37Z | `s37a-control-minimal`                          | control                         | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                                     | `b6c7a877c0de85be` | clean-open     | valid                                  | valid                           | —                               | valid                                                                                        |
| `s37a` | 08:04:37Z | `settings-numbering-control`                    | control for `s37a`              | `MINIMAL_PARTS` plus `word/settings.xml` and `word/numbering.xml` (empty roots, Overrides, related as `rId7` and `rId8`), no sidecars                                                                                                                                                                                                               | `fe6ea6904d75e41d` | clean-open     | valid                                  | valid                           | —                               | valid                                                                                        |
| `s37a` | 08:04:37Z | `settings-rels-mc-malformed-sibling`            | #644 (scope)                    | `MINIMAL_PARTS` plus `word/settings.xml` and `word/_rels/settings.xml.rels`: an empty `Relationships` holding only the malformed sibling of session 36 (`<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent>`, `xmlns:mc` on the root, `nope` undeclared)                                                         | `cafd348f63c8b8c7` | clean-open     | invalid: `opc-relationships-structure` | valid                           | —                               | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                           |
| `s37a` | 08:04:37Z | `numbering-rels-mc-malformed-sibling`           | #644 (scope)                    | the same for `word/numbering.xml`                                                                                                                                                                                                                                                                                                                   | `e7971891d39ea4a0` | clean-open     | invalid: `opc-relationships-structure` | valid                           | —                               | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`                           |
| `s37a` | 08:04:37Z | `header-rels-mc-malformed-sibling`              | #644 (scope)                    | session 26's header package (`storyReferenceParts`) plus `word/_rels/header1.xml.rels`, the same                                                                                                                                                                                                                                                    | `99402d1675b9c826` | clean-open     | invalid: `opc-relationships-structure` | valid                           | —                               | invalid: `mce-malformed`, `opc-relationships-markup-compatibility`, `paraid-missing-element` |
| `s37a` | 08:04:37Z | `styles-rels-root-mustunderstand`               | #644 (scope)                    | `MINIMAL_PARTS` plus `word/_rels/styles.xml.rels`: an empty `Relationships` whose root carries `mc:MustUnderstand="foo"` (`foo` = `urn:foo`)                                                                                                                                                                                                        | `fe26026764708e8c` | clean-open     | valid                                  | valid                           | —                               | invalid: `mce-must-understand`, `rels-empty-part`                                            |
| `s37a` | 08:04:37Z | `footer-rels-root-mustunderstand`               | #644 (scope)                    | session 26's footer package plus `word/_rels/footer1.xml.rels`, the same                                                                                                                                                                                                                                                                            | `14ccd716bab320a3` | clean-open     | valid                                  | valid                           | —                               | invalid: `mce-must-understand`, `paraid-missing-element`, `rels-empty-part`                  |
| `s37a` | 08:04:37Z | `s37a-control-minimal-end`                      | control                         | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                                     | `b6c7a877c0de85be` | clean-open     | valid                                  | valid                           | —                               | valid                                                                                        |
| `s37b` | 08:14:39Z | `s37b-control-minimal`                          | control                         | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                                     | `dc259431eeda4c9f` | clean-open     | valid                                  | valid                           | valid                           | valid                                                                                        |
| `s37b` | 08:14:39Z | `chart-word-unselected-reference-no-sidecar`    | #645 (boundary)                 | `s36d`'s referenced chart (`word/charts/chart1.xml`, a clustered bar chart, Override, no `.rels`, related from `word/_rels/document.xml.rels` as `rId9`) with `<c:externalData r:id="rId1"/>`, its inline drawing wrapped in `<mc:AlternateContent><mc:Choice Requires="foo">…</mc:Choice><mc:Fallback/></mc:AlternateContent>` (`foo` = `urn:foo`) | `5087cf4f3ee29350` | clean-open     | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | valid                           | invalid: `rels-missing-sidecar`                                                              |
| `s37b` | 08:14:32Z | `chart-word-selected-reference-no-sidecar`      | #645 (boundary)                 | the same with `Requires="w14"`                                                                                                                                                                                                                                                                                                                      | `da1312b97b120e46` | repair-warning | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                              |
| `s37b` | 08:14:39Z | `chart-word-selected-reference-no-externaldata` | control for the selected Choice | the same without `c:externalData`                                                                                                                                                                                                                                                                                                                   | `b9b5d1205c90341a` | clean-open     | valid                                  | valid                           | valid                           | valid                                                                                        |
| `s37b` | 08:14:39Z | `chart-outside-word-mixed-reach-no-sidecar`     | #647 (#645 boundary)            | `MINIMAL_PARTS` plus `s36b`'s bare chart at `charts/chart1.xml` (no `.rels`), related from `word/_rels/document.xml.rels` as `rId9` (`chart`) and `rId8` (`image`), both `../charts/chart1.xml`, referenced by nothing                                                                                                                              | `d9fcab69f2cdbbb8` | clean-open     | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary`                                  |
| `s37b` | 08:14:39Z | `s37b-control-minimal-end`                      | control                         | `MINIMAL_PARTS`                                                                                                                                                                                                                                                                                                                                     | `dc259431eeda4c9f` | clean-open     | valid                                  | valid                           | valid                           | valid                                                                                        |

<details><summary>Raw records, session 37</summary>

```jsonl
{"run": "s37a", "name": "s37a-control-minimal", "sha256": "b6c7a877c0de85beca7874c71e5e07eca66fb62d49614c11606fcebc9a49d5d4", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "settings-numbering-control", "sha256": "fe6ea6904d75e41d43e85d318281774cfe38a52d2ddd5bef97d7c7403246f55e", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "settings-rels-mc-malformed-sibling", "sha256": "cafd348f63c8b8c7ccd3c7f15a3343ff20d165dc92fa4f219bde0580289587ae", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "numbering-rels-mc-malformed-sibling", "sha256": "e7971891d39ea4a04f305db9ffd5fd6f6da4c1ffcf93bab67aa865be61363a73", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "header-rels-mc-malformed-sibling", "sha256": "99402d1675b9c8266831516647b8e61d80d16507cb0a9ea81473e66c05f1161a", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "styles-rels-root-mustunderstand", "sha256": "fe26026764708e8c33ff4d63bb144b52a58ad3fdfd77d3513741946e812b047d", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "footer-rels-root-mustunderstand", "sha256": "14ccd716bab320a3587e6bd970a92a99f5bb898192b23cba3a656b6bff46fbf2", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37a", "name": "s37a-control-minimal-end", "sha256": "b6c7a877c0de85beca7874c71e5e07eca66fb62d49614c11606fcebc9a49d5d4", "observedAt": "2026-10-25T08:04:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37b", "name": "s37b-control-minimal", "sha256": "dc259431eeda4c9fe45771633844ea4412d7bc87a8d12371e526e2731feb3e56", "observedAt": "2026-10-25T08:14:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37b", "name": "chart-word-unselected-reference-no-sidecar", "sha256": "5087cf4f3ee29350ae3a89c22153af7e8836024d463ade6bd05e0b2c73b45903", "observedAt": "2026-10-25T08:14:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37b", "name": "chart-word-selected-reference-no-sidecar", "sha256": "da1312b97b120e4633a4c8c85cc94d1618b90bd9f6aa3432b42616e32ec969c0", "observedAt": "2026-10-25T08:14:32.791Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__chart-word-selected-reference-no-sidecar.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__chart-word-selected-reference-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__chart-word-selected-reference-no-sidecar.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s37b", "name": "chart-word-selected-reference-no-externaldata", "sha256": "b9b5d1205c90341ab7c5d22dba9dbe889730a4765d79e73542c7a6138eae4826", "observedAt": "2026-10-25T08:14:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37b", "name": "chart-outside-word-mixed-reach-no-sidecar", "sha256": "d9fcab69f2cdbbb8df4017d185aad23cd7328387506cde9bb2b4a1093867e3b9", "observedAt": "2026-10-25T08:14:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s37b", "name": "s37b-control-minimal-end", "sha256": "dc259431eeda4c9fe45771633844ea4412d7bc87a8d12371e526e2731feb3e56", "observedAt": "2026-10-25T08:14:39+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 38: 08:54Z–08:57Z on 2026-10-25, validator columns at ab2e324f, 3788f719 and 4295889a

The package relationships root wrappers #646's fix accepts, with two clean controls. The driver opens the chunk's files in name order, so the controls were queued last ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Word stalled on `pkgrels-root-ac-unselected-choice-relationships`, and the driver relaunched Word and reopened it in a second pass, after the controls ([#672](https://github.com/jandira-tech/docx-validate/issues/672)).

| Run    | Observed  | Specimen                                          | Issue                     | Shape                                                                                                                                                                               | SHA-256 (first 16) | Word           | word-valid at ab2e324f                                            | word-valid at 3788f719                                                             | word-valid at 4295889a                                                             | strict at 4295889a                                                                                                                  |
| ------ | --------- | ------------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `s38a` | 08:56:38Z | `s38a-control-minimal`                            | control                   | `MINIMAL_PARTS`                                                                                                                                                                     | `3ec05e8e7996e6ee` | clean-open     | valid                                                             | valid                                                                              | valid                                                                              | valid                                                                                                                               |
| `s38a` | 08:56:38Z | `pkgrels-root-ac-fallback-relationships-recheck`  | #646 (observed in `s36c`) | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>` holding the package part's `Relationships` element (`foo` = `urn:foo`) | `477a71135e7e7c6e` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure`                                             | valid                                                                              | invalid: `xsd-error`, `xsd-summary`                                                                                                 |
| `s38a` | 08:56:38Z | `pkgrels-root-ac-choice-relationships`            | #646                      | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="w14">` holding the package part's `Relationships` element, then `<mc:Fallback/>`            | `ebe5391e4e120d69` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure`                                             | valid                                                                              | invalid: `xsd-error`, `xsd-summary`                                                                                                 |
| `s38a` | 08:56:38Z | `pkgrels-root-processcontent-relationships`       | #646                      | `MINIMAL_PARTS` with `_rels/.rels` stored as `<x:Wrap mc:Ignorable="x" mc:ProcessContent="x:Wrap">` holding the package part's `Relationships` element (`x` = `urn:x`)              | `61324c68e1ae2230` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure`                                             | valid                                                                              | invalid: `xsd-error`, `xsd-summary`                                                                                                 |
| `s38a` | 08:55:51Z | `pkgrels-root-ac-unselected-choice-relationships` | #646 (boundary)           | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo">` holding the package part's `Relationships` element, then `<mc:Fallback/>`            | `ee0d75004ccd4625` | repair-warning | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `mce-malformed`, `opc-relationships-structure`, `word-main-document-part` | invalid: `mce-malformed`, `opc-relationships-structure`, `word-main-document-part` | invalid: `mce-malformed`, `opc-relationships-structure`, `rels-unreferenced`, `word-main-document-part`, `xsd-error`, `xsd-summary` |
| `s38a` | 08:56:38Z | `s38a-control-minimal-end`                        | control                   | `MINIMAL_PARTS`                                                                                                                                                                     | `3ec05e8e7996e6ee` | clean-open     | valid                                                             | valid                                                                              | valid                                                                              | valid                                                                                                                               |

<details><summary>Raw records, session 38</summary>

```jsonl
{"run": "s38a", "name": "s38a-control-minimal", "sha256": "3ec05e8e7996e6ee68774abef26f770376465480e76b39cbce4f992ccbcc9b26", "observedAt": "2026-10-25T08:56:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s38a", "name": "pkgrels-root-ac-fallback-relationships-recheck", "sha256": "477a71135e7e7c6e212d31372a6f10c2d3bbe8304aaa9838e9bd7261ecf5bca3", "observedAt": "2026-10-25T08:56:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s38a", "name": "pkgrels-root-ac-choice-relationships", "sha256": "ebe5391e4e120d6948711743cc6ba097093ab392c019127e6da449c87a30d64d", "observedAt": "2026-10-25T08:56:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s38a", "name": "pkgrels-root-processcontent-relationships", "sha256": "61324c68e1ae2230256d7e2745d77e2d3a896943cc55c1457585a701a19da42d", "observedAt": "2026-10-25T08:56:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s38a", "name": "pkgrels-root-ac-unselected-choice-relationships", "sha256": "ee0d75004ccd4625b25873cf6f15725157df44d75e9aedd8147479b64be40a2b", "observedAt": "2026-10-25T08:55:51.964Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__pkgrels-root-ac-unselected-choice-relationships.docx; refusing to guess", "dialogs": ["\"Word found unreadable content in 00002__wfv__pkgrels-root-ac-unselected-choice-relationships..... Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "'Word found unreadable content in 00002__wfv__pkgrels-root-ac-unselected-choice-relationships..... Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s38a", "name": "s38a-control-minimal-end", "sha256": "3ec05e8e7996e6ee68774abef26f770376465480e76b39cbce4f992ccbcc9b26", "observedAt": "2026-10-25T08:56:38+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 39: 09:34Z–09:39Z on 2026-10-25, validator columns at ab2e324f, 3788f719 and 4295889a

The chart sources (#661) and package-root wrapper combinations (#662) the layer 133 review found accepted without evidence, and the referenced chart twins, with two clean controls in every chunk. The driver opens a chunk's files in name order, so the controls were queued last in every chunk ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). In `s39c` the controls opened in the driver's third pass, and specimens Word had returned nothing for reopened after them ([#672](https://github.com/jandira-tech/docx-validate/issues/672)); rows are listed in builder order.

| Run    | Observed  | Specimen                                       | Issue       | Shape                                                                                                                                                                                                                                    | SHA-256 (first 16) | Word           | word-valid at ab2e324f                                            | word-valid at 3788f719                 | word-valid at 4295889a          | strict at 4295889a                                          |
| ------ | --------- | ---------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | ----------------------------------------------------------------- | -------------------------------------- | ------------------------------- | ----------------------------------------------------------- |
| `s39a` | 09:34:29Z | `s39a-control-minimal`                         | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `c6ed84a2f2856d73` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |
| `s39a` | 09:34:29Z | `chart-header-unreferenced`                    | #661        | `MINIMAL_PARTS` plus a header the main document references, whose sidecar relates the s36d clustered bar chart `word/charts/chart1.xml` (dangling `c:externalData r:id`, no sidecar) as `rId9`; nothing names `rId9`                     | `7d5241c17d9a533d` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39a` | 09:34:29Z | `chart-footnote-unreferenced`                  | #661        | a reached glossary whose footnotes part's sidecar relates the s36d clustered bar chart `word/charts/chart1.xml` (dangling `c:externalData r:id`, no sidecar) as `rId9`; nothing names `rId9`                                             | `e7662793551bdd66` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39a` | 09:34:29Z | `chart-glossary-unreferenced`                  | #661        | a reached glossary whose document's sidecar relates the s36d clustered bar chart `word/charts/chart1.xml` (dangling `c:externalData r:id`, no sidecar) as `rId9`; nothing names `rId9`                                                   | `b618ee1dc9c9fb8e` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39a` | 09:34:29Z | `chart-unselected-fallback`                    | #661        | the s36d clustered bar chart `word/charts/chart1.xml` (dangling `c:externalData r:id`, no sidecar) related as `rId9`; the main document's drawing naming it sits only in `<mc:AlternateContent><mc:Choice Requires="w14"/><mc:Fallback>` | `882d8c7da99a34eb` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `rels-missing-sidecar`                             |
| `s39a` | 09:34:29Z | `chart-two-relationships-no-references`        | #661        | the s36b bare chart `word/charts/chart1.xml` (a bare `c:plotArea`, dangling `c:externalData r:id`, no sidecar) related by the main document as `rId9` and `rId8`; nothing names either                                                   | `6284ceba197625d0` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary` |
| `s39a` | 09:34:29Z | `chart-equivalent-target-unreferenced`         | #661        | the s36b bare chart `word/charts/chart1.xml` (a bare `c:plotArea`, dangling `c:externalData r:id`, no sidecar) related as `rId9` with `Target="CHARTS/%63hart1.xml"`; nothing names `rId9`                                               | `1c081590957bc651` | clean-open     | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | valid                           | invalid: `rels-missing-sidecar`, `xsd-error`, `xsd-summary` |
| `s39a` | 09:34:29Z | `s39a-control-minimal-end`                     | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `c6ed84a2f2856d73` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |
| `s39b` | 09:35:02Z | `s39b-control-minimal`                         | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `3159271c0d644744` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |
| `s39b` | 09:35:02Z | `package-root-nested-fallback`                 | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>` holding a second such wrapper whose Fallback holds the package part's `Relationships` element                               | `9ccf796a2033f3fb` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `package-root-three-nested-fallback`           | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as three nested `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>` wrappers around the package part's `Relationships` element                                                     | `f5f7164064cad9c4` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `package-root-multiple-choices`                | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Choice Requires="w14">` holding the package part's `Relationships` element, then `<mc:Fallback/>`                                      | `f04688ea800e34d4` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `package-root-first-of-two-understood-choices` | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as two `<mc:Choice Requires="w14">`, the first holding the package part's `Relationships` element, the second `<foo:bad/>`, then `<mc:Fallback/>`                                              | `c1e962189097235f` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `package-root-mustunderstand-w14`              | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>` holding the package part's `Relationships` element, the AlternateContent carrying `mc:MustUnderstand="w14"`                 | `5b068fd4eb0f6336` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `package-root-ignorable-child`                 | #662        | `MINIMAL_PARTS` with `_rels/.rels` stored as `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>` holding the package part's `Relationships` element with `mc:Ignorable="foo"` and a `<foo:bad/>` child                       | `2b8696a9abe9c303` | clean-open     | invalid: `opc-relationships-structure`, `word-main-document-part` | invalid: `opc-relationships-structure` | valid                           | invalid: `xsd-error`, `xsd-summary`                         |
| `s39b` | 09:35:02Z | `s39b-control-minimal-end`                     | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `3159271c0d644744` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |
| `s39c` | 09:39:37Z | `s39c-control-minimal`                         | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `9f7a3eb4f36859a7` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |
| `s39c` | 09:37:21Z | `chart-header-referenced`                      | #661 (twin) | `chart-header-unreferenced` with the s36d drawing naming `rId9` before the header's paragraph                                                                                                                                            | `9295270440c6ce2a` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39c` | 09:36:17Z | `chart-footnote-referenced`                    | #661 (twin) | `chart-footnote-unreferenced` with the drawing before the footnotes part's first paragraph                                                                                                                                               | `e6726a3858dad562` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39c` | 09:37:02Z | `chart-glossary-referenced`                    | #661 (twin) | `chart-glossary-unreferenced` with the drawing before the glossary document's first paragraph                                                                                                                                            | `68529f0b0e785513` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `paraid-missing-element`, `rels-missing-sidecar`   |
| `s39c` | 09:37:25Z | `chart-selected-fallback`                      | #661 (twin) | `chart-unselected-fallback` with `Requires="foo"`, so Word selects the Fallback holding the drawing                                                                                                                                      | `4151aa20fc393248` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                             |
| `s39c` | 09:38:14Z | `chart-two-relationships-one-reference`        | #661 (twin) | `chart-two-relationships-no-references` with the drawing naming `rId9` and the s36d clustered bar chart in place of the bare one                                                                                                         | `38692fa07ce8d1fc` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                             |
| `s39c` | 09:35:31Z | `chart-equivalent-target-referenced`           | #661 (twin) | `chart-equivalent-target-unreferenced` with the drawing naming `rId9` and the s36d clustered bar chart in place of the bare one                                                                                                          | `a56b728ca9a3ab7b` | repair-warning | invalid: `rels-missing-sidecar`                                   | invalid: `rels-missing-sidecar`        | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                             |
| `s39c` | 09:39:37Z | `s39c-control-minimal-end`                     | control     | `MINIMAL_PARTS`                                                                                                                                                                                                                          | `9f7a3eb4f36859a7` | clean-open     | valid                                                             | valid                                  | valid                           | valid                                                       |

<details><summary>Raw records, session 39</summary>

```jsonl
{"run": "s39a", "name": "s39a-control-minimal", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-header-unreferenced", "sha256": "7d5241c17d9a533d31a0fda0375b529f889d2e329ecea72bce3b32d67384ab2c", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-footnote-unreferenced", "sha256": "e7662793551bdd668fc097938c4cf34713dbed4449f129fd373da9d95239fb6e", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-glossary-unreferenced", "sha256": "b618ee1dc9c9fb8e60fcf165c1d57b3ba35215a404e00b6127a412a81c07c8de", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-unselected-fallback", "sha256": "882d8c7da99a34eba8e901989d8b417c4734810cb8660177842d1e92d5f56bbc", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-two-relationships-no-references", "sha256": "6284ceba197625d09663a2247a5e19fd3cc15052dec7b3ef97001b516cd2b2c8", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "chart-equivalent-target-unreferenced", "sha256": "1c081590957bc65116e942e2667f0b5aa46b1d1beae96d47360327fabc6077ab", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39a", "name": "s39a-control-minimal-end", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "observedAt": "2026-10-25T09:34:29+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "s39b-control-minimal", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-nested-fallback", "sha256": "9ccf796a2033f3fbda906327851e7cc1d7740646a3f177305f4f48886a424432", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-three-nested-fallback", "sha256": "f5f7164064cad9c488545e4d5b47dcf96d6c199d463004f43945496479319860", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-multiple-choices", "sha256": "f04688ea800e34d49f20589b4f577dc8c3225bfb577485f32a3e329b499d9892", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-first-of-two-understood-choices", "sha256": "c1e962189097235f640801e6fd9f9a485ac7b3953dc0b3a581d2606b3c06dfb0", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-mustunderstand-w14", "sha256": "5b068fd4eb0f6336922952e085197660700b5d61c4d172e3c8a74432c9ad2557", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "package-root-ignorable-child", "sha256": "2b8696a9abe9c30392e71590d5960c28b57cf08f28bc7c8babc4a33184c3fe79", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39b", "name": "s39b-control-minimal-end", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "observedAt": "2026-10-25T09:35:02+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39c", "name": "s39c-control-minimal", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "observedAt": "2026-10-25T09:39:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s39c", "name": "chart-header-referenced", "sha256": "9295270440c6ce2a141667a75b8340f4a6e1b005b62dd7cf5ec7f7b67431435b", "observedAt": "2026-10-25T09:37:21.548Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__chart-header-referenced.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter.", "'Word found unreadable content in 00003__wfv__chart-header-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00003__wfv__chart-header-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s39c", "name": "chart-footnote-referenced", "sha256": "e6726a3858dad562b09603e6db5fe94663c562fc8cf98b3e885043d69de66c22", "observedAt": "2026-10-25T09:36:17.361Z", "outcome": "repair-warning", "item": "failed", "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__chart-footnote-referenced.docx; refusing to guess", "dialogs": ["'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure there is sufficient free memory and disk space.\\n* Open the file with the Text Recovery conver", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter.", "'Word found unreadable content in 00001__wfv__chart-footnote-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00001__wfv__chart-footnote-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s39c", "name": "chart-glossary-referenced", "sha256": "68529f0b0e785513f2edf004be2d70958e17e527cbe91f1b9fded7a142c6fb24", "observedAt": "2026-10-25T09:37:02.026Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__chart-glossary-referenced.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00002__wfv__chart-glossary-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00002__wfv__chart-glossary-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\""]}
{"run": "s39c", "name": "chart-selected-fallback", "sha256": "4151aa20fc39324819fde0c2015fcf5f8252cc458f75c64474392c6a119834d6", "observedAt": "2026-10-25T09:37:25.830Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__chart-selected-fallback.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00004__wfv__chart-selected-fallback.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00004__wfv__chart-selected-fallback.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s39c", "name": "chart-two-relationships-one-reference", "sha256": "38692fa07ce8d1fcfd4a72bcf8192e9a1876b1a28a0b77f3cf88888e52554048", "observedAt": "2026-10-25T09:38:14.974Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__chart-two-relationships-one-reference.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00005__wfv__chart-two-relationships-one-reference.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00005__wfv__chart-two-relationships-one-reference.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s39c", "name": "chart-equivalent-target-referenced", "sha256": "a56b728ca9a3ab7bea131f935d4a156f04fd47b4d32678676539ea87750cb06e", "observedAt": "2026-10-25T09:35:31.007Z", "outcome": "repair-warning", "item": "failed", "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__chart-equivalent-target-referenced.docx; refusing to guess", "dialogs": ["'Word found unreadable content in 00000__wfv__chart-equivalent-target-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.'", "\"Word found unreadable content in 00000__wfv__chart-equivalent-target-referenced.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.\"", "\"Word experienced an error trying to open the file.\nTry these suggestions.\n* Check the file permissions for the document or drive.\n* Make sure there is sufficient free memory and disk space.\n* Open the file with the Text Recovery converter."]}
{"run": "s39c", "name": "s39c-control-minimal-end", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "observedAt": "2026-10-25T09:39:37+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 40: 23:22Z–23:23Z on 2026-10-25, validator columns at f3bbf27c and 0e06e03e

The paragraph-id repair's output (#653) and the External relationship targets Word-valid blocked (#665), with two clean controls in each chunk. The driver opens a chunk's files in name order, so the controls were queued last in both chunks ([#671](https://github.com/jandira-tech/docx-validate/issues/671)); rows are listed in builder order.

| Run    | Observed  | Specimen                              | Issue          | Shape                                                                                                                                                                                                                       | SHA-256 (first 16) | Word       | word-valid at f3bbf27c | word-valid at 0e06e03e | strict at f3bbf27c                                               | strict at 0e06e03e                                |
| ------ | --------- | ------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ---------- | ---------------------- | ---------------------- | ---------------------------------------------------------------- | ------------------------------------------------- |
| `s40a` | 23:22:46Z | `s40a-control-minimal`                | control        | `MINIMAL_PARTS`                                                                                                                                                                                                             | `b705a9a7e3509d7e` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40a` | 23:22:46Z | `653-repaired-root-w14`               | #653           | a main document of two paragraphs and a one-row table, none with ids, its root declaring neither `w14` nor `mc`, after `repairMissingParaIds`: the root gains `xmlns:mc`, `xmlns:w14` and `mc:Ignorable="w14"`              | `7b2cb42973cc82d3` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40a` | 23:22:46Z | `653-repaired-root-w14-w15`           | #653           | a main document of two paragraphs and a one-row table, none with ids, its root declaring `w15` and `mc` with `mc:Ignorable="w15"`, after the repair: `mc:Ignorable="w15 w14"`                                               | `52480de21e92f6ae` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40a` | 23:22:46Z | `653-repaired-compat-prefix`          | #653           | a main document of two paragraphs and a one-row table, none with ids, its root binding the compatibility namespace to `compat` with `compat:Ignorable="w15"`, after the repair: `compat:Ignorable="w15 w14"`, no `xmlns:mc` | `dc820d6932ebe9d9` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40a` | 23:22:46Z | `653-release-repair-shape`            | #653 (release) | `653-repaired-root-w14` with the root left as it was and `xmlns:w14` on each stamped paragraph and row, release's output                                                                                                    | `26e3d0785d441cab` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40a` | 23:22:46Z | `665-external-file-pdf-direct`        | #665           | `MINIMAL_PARTS` plus an External hyperlink relationship `rId9` in `word/_rels/document.xml.rels` to `file:///C:/missing.pdf`; nothing names `rId9`                                                                          | `dc107a1ce7d34d0b` | clean-open | valid                  | valid                  | invalid: `rels-broken`                                           | valid                                             |
| `s40a` | 23:22:46Z | `665-external-file-rels-direct`       | #665           | `MINIMAL_PARTS` plus an External hyperlink relationship `rId9` in `word/_rels/document.xml.rels` to `file:///missing.rels`; nothing names `rId9`                                                                            | `b8fe307421d13074` | clean-open | invalid: `rels-broken` | valid                  | invalid: `rels-broken`                                           | valid                                             |
| `s40a` | 23:22:46Z | `s40a-control-minimal-end`            | control        | `MINIMAL_PARTS`                                                                                                                                                                                                             | `c1de2b26fda5b35c` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40b` | 23:23:01Z | `s40b-control-minimal`                | control        | `MINIMAL_PARTS`                                                                                                                                                                                                             | `b72f9778371a8f0d` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |
| `s40b` | 23:23:01Z | `665-external-file-rels-choice`       | #665           | `665-external-file-rels-direct` with the relationship inside `<mc:AlternateContent><mc:Choice Requires="w14">`, beside an empty Fallback                                                                                    | `c91edf5cc7229093` | clean-open | invalid: `rels-broken` | valid                  | invalid: `opc-relationships-markup-compatibility`, `rels-broken` | invalid: `opc-relationships-markup-compatibility` |
| `s40b` | 23:23:01Z | `665-external-underscore-rels-direct` | #665           | `MINIMAL_PARTS` plus an External hyperlink relationship `rId9` in `word/_rels/document.xml.rels` to `file:///C:/docs/_rels/missing.xml`; nothing names `rId9`                                                               | `36c2647c125e7f9f` | clean-open | invalid: `rels-broken` | valid                  | invalid: `rels-broken`                                           | valid                                             |
| `s40b` | 23:23:01Z | `665-external-underscore-rels-choice` | #665           | `665-external-underscore-rels-direct` with the relationship inside `<mc:AlternateContent><mc:Choice Requires="w14">`, beside an empty Fallback                                                                              | `5e30a31fa5b4f429` | clean-open | invalid: `rels-broken` | valid                  | invalid: `opc-relationships-markup-compatibility`, `rels-broken` | invalid: `opc-relationships-markup-compatibility` |
| `s40b` | 23:23:01Z | `665-external-customxml-direct`       | #665           | `MINIMAL_PARTS` plus an External hyperlink relationship `rId9` in `word/_rels/document.xml.rels` to `../customXml/missing.xml`; nothing names `rId9`                                                                        | `20857bf27a053f2c` | clean-open | invalid: `rels-broken` | valid                  | invalid: `rels-broken`                                           | valid                                             |
| `s40b` | 23:23:01Z | `665-external-customxml-choice`       | #665           | `665-external-customxml-direct` with the relationship inside `<mc:AlternateContent><mc:Choice Requires="w14">`, beside an empty Fallback                                                                                    | `ddb88d905e1d0255` | clean-open | invalid: `rels-broken` | valid                  | invalid: `opc-relationships-markup-compatibility`, `rels-broken` | invalid: `opc-relationships-markup-compatibility` |
| `s40b` | 23:23:01Z | `665-external-file-rels-referenced`   | #665           | `665-external-file-rels-direct` with the main document's run inside `<w:hyperlink r:id="rId9">`                                                                                                                             | `a09d694c5a0e5549` | clean-open | invalid: `rels-broken` | valid                  | invalid: `rels-broken`                                           | valid                                             |
| `s40b` | 23:23:01Z | `s40b-control-minimal-end`            | control        | `MINIMAL_PARTS`                                                                                                                                                                                                             | `b72f9778371a8f0d` | clean-open | valid                  | valid                  | valid                                                            | valid                                             |

<details><summary>Raw records, session 40</summary>

```jsonl
{"run": "s40a", "name": "s40a-control-minimal", "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "653-repaired-root-w14", "sha256": "7b2cb42973cc82d3eb7750676e7c6b1ece6b0586589370923db09ea78c860423", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "653-repaired-root-w14-w15", "sha256": "52480de21e92f6aec47e367e23db2673ff70527ac5a63fc006cc6ce55f7155b0", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "653-repaired-compat-prefix", "sha256": "dc820d6932ebe9d9ef85f50531b005ebb5d9800e21bc6ffe9b994bf27457feb2", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "653-release-repair-shape", "sha256": "26e3d0785d441caba7a25211d8a5907936334f353835a4d7ca420509592258ad", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "665-external-file-pdf-direct", "sha256": "dc107a1ce7d34d0b610dd7069df6e003774b90d3d1a03ba76fd7b2d3cb9b953e", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "665-external-file-rels-direct", "sha256": "b8fe307421d13074da756dad858475874094409a901969fd3fa4a9809ab335f1", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40a", "name": "s40a-control-minimal-end", "sha256": "c1de2b26fda5b35cad7b5a9f4a70535a8c7cdd5d31ad02080dc20f0e4a1c2092", "observedAt": "2026-10-25T23:22:46+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "s40b-control-minimal", "sha256": "b72f9778371a8f0d3227bc22d3b4637ce79a61debf4b50307b33ca882fdf97a4", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-file-rels-choice", "sha256": "c91edf5cc72290931447f9cfcb0f6b98ebe75024b457e2e5e96c1ed1198f4d31", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-underscore-rels-direct", "sha256": "36c2647c125e7f9f538272417f14b5d88ffe56a6e06335a5a5047711f175a8ce", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-underscore-rels-choice", "sha256": "5e30a31fa5b4f429fbbbd4cf082428890f38819817af639f52b99c02a07cd996", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-customxml-direct", "sha256": "20857bf27a053f2cb7773f99fa77bada8275d3cbd2043dae9016293b52b28618", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-customxml-choice", "sha256": "ddb88d905e1d02556ad9047dfa4924755252ad114d340acfb911d4f15c2217db", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "665-external-file-rels-referenced", "sha256": "a09d694c5a0e5549176dea86141c96c6b0263677cf8175abc3f1bb5000e674a5", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
{"run": "s40b", "name": "s40b-control-minimal-end", "sha256": "b72f9778371a8f0d3227bc22d3b4637ce79a61debf4b50307b33ca882fdf97a4", "observedAt": "2026-10-25T23:23:01+00:00", "outcome": "clean-open", "item": "ok", "error": "", "dialogs": []}
```

</details>

### Session 41: 01:16Z–01:52Z on 2026-10-26, validator columns at c0a244f5

The 56 package fixtures layer 136 pins: the 29 `tests/fixtures/broken/package.*` single-defect specimens and their 27 `tests/fixtures/working/package.*` twins, in eight chunks of seven with each pair adjacent and a clean control queued last in every chunk ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Every chunk ran twice, as two separate driver runs of byte-identical copies. Each run's rows were read twice: from its own Word log (`logcheck.py`, below) and by `wordpdf_outcomes.py`. A row counts only when both runs and both readings agree, and all 64 do. The two times in Observed are the ends of the first and second runs. Rows are listed in staging order; the driver opens a chunk's files in name order.

| Run    | Observed             | Fixture                                                         | SHA-256 (first 16) | Word, run 1    | Word, run 2    | word-valid at c0a244f5                                                     | strict at c0a244f5                                                                                                                                                                         |
| ------ | -------------------- | --------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `s41a` | 01:18:27Z, 01:30:59Z | `broken/package.drawing-arc-radius.docx`                        | `8515c035158cbdad` | open-error     | open-error     | invalid: `word-drawing-arc-radius`                                         | invalid: `paraid-missing-element`, `style-default-missing`, `word-drawing-arc-radius`                                                                                                      |
| `s41a` | 01:18:27Z, 01:30:59Z | `working/package.drawing-arc-radius-integer.docx`               | `d6faf27e24b0d540` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41a` | 01:18:27Z, 01:30:59Z | `broken/package.word-anchor-open.docx`                          | `9c0b13c74c82a6fd` | open-error     | open-error     | invalid: `word-anchor-missing-attribute`, `word-position-offset-and-align` | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `word-anchor-missing-attribute`, `word-position-offset-and-align`, `xsd-error`, `xsd-summary`             |
| `s41a` | 01:18:27Z, 01:30:59Z | `working/package.word-anchor-open-repaired.docx`                | `f38a49e7a7eb4523` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `xsd-error`, `xsd-summary`                                                                                |
| `s41a` | 01:18:27Z, 01:30:59Z | `broken/package.word-attached-toolbar-utf8.docx`                | `b0cf666af937209d` | repair-warning | repair-warning | invalid: `word-attached-toolbar-utf8`                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `word-attached-toolbar-utf8`, `xsd-error`, `xsd-summary`                                                  |
| `s41a` | 01:18:27Z, 01:30:59Z | `working/package.word-attached-toolbar-utf8-repaired.docx`      | `864227204267541a` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `xsd-error`, `xsd-summary`                                                                                |
| `s41a` | 01:18:27Z, 01:30:59Z | `broken/package.word-cell-ends-with-table.docx`                 | `c63ee16523e32bfa` | repair-warning | repair-warning | invalid: `word-cell-ends-with-table`                                       | invalid: `paraid-missing-element`, `word-cell-ends-with-table`, `xsd-error`, `xsd-summary`                                                                                                 |
| `s41a` | 01:18:27Z, 01:30:59Z | `s41a-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41b` | 01:21:39Z, 01:33:24Z | `working/package.word-cell-ends-with-table-repaired.docx`       | `f43be4fc8ad3ba0a` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                                                                                              |
| `s41b` | 01:21:39Z, 01:33:24Z | `broken/package.word-choice-requires-on-descendant.docx`        | `a8e728c4107c1487` | repair-warning | repair-warning | invalid: `mce-malformed`, `word-choice-requires-undeclared`                | invalid: `mce-malformed`, `word-choice-requires-undeclared`, `xsd-error`, `xsd-summary`                                                                                                    |
| `s41b` | 01:21:39Z, 01:33:24Z | `working/package.word-choice-requires-on-ancestor.docx`         | `aa69a3c4b3448b80` | clean-open     | clean-open     | valid                                                                      | invalid: `xsd-error`, `xsd-summary`                                                                                                                                                        |
| `s41b` | 01:21:39Z, 01:33:24Z | `broken/package.word-choice-requires-undeclared.docx`           | `f2bdb740a3021200` | repair-warning | repair-warning | invalid: `mce-malformed`, `word-choice-requires-undeclared`                | invalid: `mce-malformed`, `word-choice-requires-undeclared`, `xsd-error`, `xsd-summary`                                                                                                    |
| `s41b` | 01:21:39Z, 01:33:24Z | `working/package.word-choice-requires-declared.docx`            | `733d1afd84bd7711` | clean-open     | clean-open     | valid                                                                      | invalid: `xsd-error`, `xsd-summary`                                                                                                                                                        |
| `s41b` | 01:21:39Z, 01:33:24Z | `broken/package.word-drawing-extent-negative-cx.docx`           | `de461e33bc71af0b` | open-error     | open-error     | invalid: `word-drawing-extent-negative`                                    | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `word-drawing-extent-negative`, `xsd-error`, `xsd-summary`                                                |
| `s41b` | 01:21:39Z, 01:33:24Z | `broken/package.word-drawing-extent-negative-cy.docx`           | `2c44584a5038057a` | open-error     | open-error     | invalid: `word-drawing-extent-negative`                                    | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `word-drawing-extent-negative`, `xsd-error`, `xsd-summary`                                                |
| `s41b` | 01:21:39Z, 01:33:24Z | `s41b-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41c` | 01:23:35Z, 01:36:14Z | `broken/package.word-drawing-extent-negative.docx`              | `4de3548ff70a39ae` | open-error     | open-error     | invalid: `word-drawing-extent-negative`                                    | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `word-drawing-extent-negative`, `xsd-error`, `xsd-summary`                                                |
| `s41c` | 01:23:35Z, 01:36:14Z | `working/package.word-drawing-extent-positive.docx`             | `9d143beaf514b30b` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `xsd-error`, `xsd-summary`                                                                                |
| `s41c` | 01:23:35Z, 01:36:14Z | `broken/package.word-duplicate-font-table.docx`                 | `bfd789dc181637f8` | repair-warning | repair-warning | invalid: `word-duplicate-font-table-relationship`                          | invalid: `paraid-missing-element`, `word-duplicate-font-table-relationship`                                                                                                                |
| `s41c` | 01:23:35Z, 01:36:14Z | `working/package.word-duplicate-font-table-removed.docx`        | `c5f6255afe8ce412` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`                                                                                                                                                          |
| `s41c` | 01:23:35Z, 01:36:14Z | `broken/package.word-duplicate-settings.docx`                   | `f9ee736e620997bc` | repair-warning | repair-warning | invalid: `word-duplicate-settings-relationship`                            | invalid: `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`, `style-default-missing`, `word-duplicate-settings-relationship`                                                 |
| `s41c` | 01:23:35Z, 01:36:14Z | `working/package.word-duplicate-settings-removed.docx`          | `97c58c1673774516` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`, `style-default-missing`                                                                                         |
| `s41c` | 01:23:35Z, 01:36:14Z | `broken/package.word-duplicate-theme.docx`                      | `52b18dea69dafe56` | repair-warning | repair-warning | invalid: `word-duplicate-theme-relationship`                               | invalid: `paraid-missing-element`, `word-duplicate-theme-relationship`, `xsd-error`, `xsd-summary`                                                                                         |
| `s41c` | 01:23:35Z, 01:36:14Z | `s41c-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41d` | 01:26:26Z, 01:38:40Z | `working/package.word-duplicate-theme-removed.docx`             | `c041b18223a6c3d8` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `xsd-error`, `xsd-summary`                                                                                                                              |
| `s41d` | 01:26:26Z, 01:38:40Z | `broken/package.word-duplicate-web-settings.docx`               | `7677b35b052b3b02` | repair-warning | repair-warning | invalid: `word-duplicate-web-settings-relationship`                        | invalid: `paraid-missing-element`, `rels-unreferenced`, `word-duplicate-web-settings-relationship`, `xsd-error`, `xsd-summary`                                                             |
| `s41d` | 01:26:26Z, 01:38:40Z | `working/package.word-duplicate-web-settings-removed.docx`      | `09c5d3aa41689640` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `xsd-error`, `xsd-summary`                                                                                                         |
| `s41d` | 01:26:26Z, 01:38:40Z | `broken/package.word-empty-drawing.docx`                        | `f6a4a0e2791d944d` | open-error     | open-error     | invalid: `word-empty-drawing`                                              | invalid: `paraid-missing-element`, `word-empty-drawing`                                                                                                                                    |
| `s41d` | 01:26:26Z, 01:38:40Z | `working/package.word-empty-drawing-removed.docx`               | `12ff28d9e5aad5fe` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`                                                                                                                                                          |
| `s41d` | 01:26:26Z, 01:38:40Z | `broken/package.word-footnote-reference-missing.docx`           | `14a04529bcd71e09` | repair-warning | repair-warning | invalid: `word-footnote-reference-missing`                                 | invalid: `paraid-missing-element`, `style-default-missing`, `word-footnote-reference-missing`                                                                                              |
| `s41d` | 01:26:26Z, 01:38:40Z | `working/package.word-footnote-reference-present.docx`          | `9acfb475b6827c78` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41d` | 01:26:26Z, 01:38:40Z | `s41d-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41e` | 01:40:41Z, 01:44:57Z | `broken/package.word-hyperlink-relationship.docx`               | `e22002e4f186a710` | repair-warning | repair-warning | invalid: `word-hyperlink-relationship`                                     | invalid: `paraid-missing-element`, `rels-id-missing`, `rels-unreferenced`, `style-default-missing`, `style-reference-undefined`, `word-hyperlink-relationship`, `xsd-error`, `xsd-summary` |
| `s41e` | 01:40:41Z, 01:44:57Z | `working/package.word-hyperlink-relationship-repaired.docx`     | `4478c5ddcdca6f88` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `style-reference-undefined`, `xsd-error`, `xsd-summary`                                                   |
| `s41e` | 01:40:41Z, 01:44:57Z | `broken/package.word-move-from-deleted-text.docx`               | `18d72b31b7f3c6ce` | repair-warning | repair-warning | invalid: `word-move-from-deleted-text`                                     | invalid: `word-move-from-deleted-text`                                                                                                                                                     |
| `s41e` | 01:40:41Z, 01:44:57Z | `working/package.word-move-from-text.docx`                      | `e03de7c960730f8a` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41e` | 01:40:41Z, 01:44:57Z | `broken/package.word-numbering-picture-bullet.docx`             | `4158815657718767` | repair-warning | repair-warning | invalid: `word-numbering-picture-bullet`                                   | invalid: `paraid-missing-element`, `style-default-missing`, `word-numbering-picture-bullet`                                                                                                |
| `s41e` | 01:40:41Z, 01:44:57Z | `working/package.word-numbering-picture-bullet-removed.docx`    | `09dd6ad583d32301` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41e` | 01:40:41Z, 01:44:57Z | `broken/package.word-row-without-cell.docx`                     | `27e6f7ace511f4b7` | open-error     | open-error     | invalid: `word-row-without-cell`                                           | invalid: `paraid-missing-element`, `rels-unreferenced`, `word-row-without-cell`, `xsd-error`, `xsd-summary`                                                                                |
| `s41e` | 01:40:41Z, 01:44:57Z | `s41e-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41f` | 01:46:08Z, 01:46:50Z | `working/package.word-row-without-cell-repaired.docx`           | `4611517d964637ba` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `xsd-error`, `xsd-summary`                                                                                                         |
| `s41f` | 01:46:08Z, 01:46:50Z | `broken/package.word-sdt-id-empty.docx`                         | `6db54e9f4fb36535` | open-error     | open-error     | invalid: `word-sdt-id-empty`                                               | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `style-reference-undefined`, `textid-missing-element`, `word-sdt-id-empty`, `xsd-error`, `xsd-summary`    |
| `s41f` | 01:46:08Z, 01:46:50Z | `working/package.word-sdt-id-empty-repaired.docx`               | `57b2598340c97dd6` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `style-reference-undefined`, `textid-missing-element`, `xsd-error`, `xsd-summary`                         |
| `s41f` | 01:46:08Z, 01:46:50Z | `broken/package.word-text-contains-paragraph.docx`              | `f494c423cca2db7e` | open-error     | open-error     | invalid: `word-text-contains-paragraph`                                    | invalid: `paraid-missing-element`, `style-default-missing`, `word-text-contains-paragraph`, `ws-missing-preserve`, `xsd-error`, `xsd-summary`                                              |
| `s41f` | 01:46:08Z, 01:46:50Z | `working/package.word-text-contains-paragraph-lifted.docx`      | `4e6e9576e2afaf61` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`, `ws-missing-preserve`                                                                                                          |
| `s41f` | 01:46:08Z, 01:46:50Z | `broken/package.word-textbox-choice-deleted-text.docx`          | `4b0a74cbc918f39b` | repair-warning | repair-warning | invalid: `word-textbox-deleted-text`                                       | invalid: `paraid-missing-element`, `style-default-missing`, `word-textbox-deleted-text`                                                                                                    |
| `s41f` | 01:46:08Z, 01:46:50Z | `working/package.word-textbox-fallback-deleted-text.docx`       | `13e0bbd7a9dbb622` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41f` | 01:46:08Z, 01:46:50Z | `s41f-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41g` | 01:48:46Z, 01:50:12Z | `broken/package.word-textbox-deleted-instruction.docx`          | `9e517b0313071113` | repair-warning | repair-warning | invalid: `word-textbox-deleted-text`                                       | invalid: `paraid-missing-element`, `style-default-missing`, `word-textbox-deleted-text`                                                                                                    |
| `s41g` | 01:48:46Z, 01:50:12Z | `working/package.word-textbox-inner-deletion.docx`              | `27aebeace127c63f` | clean-open     | clean-open     | valid                                                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `style-reference-undefined`                                                                                            |
| `s41g` | 01:48:46Z, 01:50:12Z | `broken/package.word-textbox-deleted-text-shape.docx`           | `25d4f44a585a61ed` | repair-warning | repair-warning | invalid: `word-textbox-deleted-text`                                       | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `style-reference-undefined`, `word-textbox-deleted-text`                                                               |
| `s41g` | 01:48:46Z, 01:50:12Z | `working/package.word-textbox-deleted-text-shape-repaired.docx` | `e2442d5e2dbea0bb` | clean-open     | clean-open     | valid                                                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `style-reference-undefined`                                                                                            |
| `s41g` | 01:48:46Z, 01:50:12Z | `broken/package.word-textbox-deleted-text.docx`                 | `b71ae90db9278fc4` | repair-warning | repair-warning | invalid: `word-textbox-deleted-text`                                       | invalid: `paraid-missing-element`, `style-default-missing`, `word-textbox-deleted-text`                                                                                                    |
| `s41g` | 01:48:46Z, 01:50:12Z | `working/package.word-textbox-deleted-text-removed.docx`        | `43dcec487eecd545` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41g` | 01:48:46Z, 01:50:12Z | `broken/package.word-undeclared-part.docx`                      | `cafddc356260ee3c` | repair-warning | repair-warning | invalid: `ct-uncovered-part`                                               | invalid: `ct-uncovered-part`, `paraid-missing-element`, `rels-unreferenced`, `style-default-missing`, `xsd-error`, `xsd-summary`                                                           |
| `s41g` | 01:48:46Z, 01:50:12Z | `s41g-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |
| `s41h` | 01:51:13Z, 01:52:16Z | `working/package.word-undeclared-part-removed.docx`             | `242448a0186ae5f8` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`, `xsd-error`, `xsd-summary`                                                                                                     |
| `s41h` | 01:51:13Z, 01:52:16Z | `broken/package.zip-bytes-after-eocd.docx`                      | `3242542fbdde1254` | repair-warning | repair-warning | invalid: `zip-bytes-after-eocd`                                            | invalid: `paraid-missing-element`, `style-default-missing`, `zip-bytes-after-eocd`                                                                                                         |
| `s41h` | 01:51:13Z, 01:52:16Z | `working/package.zip-no-bytes-after-eocd.docx`                  | `77d15a55769074cf` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41h` | 01:51:13Z, 01:52:16Z | `broken/package.zip-concatenated-copy.docx`                     | `8ab8b60226479424` | repair-warning | repair-warning | invalid: `zip-bytes-before-archive`                                        | invalid: `paraid-missing-element`, `style-default-missing`, `zip-bytes-before-archive`                                                                                                     |
| `s41h` | 01:51:13Z, 01:52:16Z | `working/package.zip-concatenated-copy-removed.docx`            | `f0e727413740038c` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`, `style-default-missing`                                                                                                                                 |
| `s41h` | 01:51:13Z, 01:52:16Z | `broken/package.zip-eocd-comment-overrun.docx`                  | `51f7d2c2f5251466` | repair-warning | repair-warning | invalid: `package-open-failed`, `zip-eocd-comment-overrun`                 | invalid: `package-open-failed`, `zip-eocd-comment-overrun`                                                                                                                                 |
| `s41h` | 01:51:13Z, 01:52:16Z | `working/package.zip-eocd-comment-declared.docx`                | `4ef5194f3cfbd1f0` | clean-open     | clean-open     | valid                                                                      | invalid: `paraid-missing-element`                                                                                                                                                          |
| `s41h` | 01:51:13Z, 01:52:16Z | `s41h-control-minimal` (control)                                | `b705a9a7e3509d7e` | clean-open     | clean-open     | valid                                                                      | valid                                                                                                                                                                                      |

<details><summary>Raw records, session 41</summary>

```jsonl
{"run": "s41a", "pass": 1, "name": "package.drawing-arc-radius", "relativePath": "broken/package.drawing-arc-radius.docx", "sha256": "8515c035158cbdade8cef3276a4240d7f605e41cf444bd5ebe5d4171ab725be2", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00001__wfv__package.drawing-arc-radius.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:16:27.796 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41a", "pass": 2, "name": "package.drawing-arc-radius", "relativePath": "broken/package.drawing-arc-radius.docx", "sha256": "8515c035158cbdade8cef3276a4240d7f605e41cf444bd5ebe5d4171ab725be2", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00001__wfv__package.drawing-arc-radius.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:29:25.651 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__package.drawing-arc-radiu...)'"]}
{"run": "s41a", "pass": 1, "name": "package.drawing-arc-radius-integer", "relativePath": "working/package.drawing-arc-radius-integer.docx", "sha256": "d6faf27e24b0d540d0d3a35dc065f23d2cb98da5ca2312e03780aa7b52b0b5da", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00000__wfv__package.drawing-arc-radius-integer.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.drawing-arc-radius-integer_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 2, "name": "package.drawing-arc-radius-integer", "relativePath": "working/package.drawing-arc-radius-integer.docx", "sha256": "d6faf27e24b0d540d0d3a35dc065f23d2cb98da5ca2312e03780aa7b52b0b5da", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00000__wfv__package.drawing-arc-radius-integer.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.drawing-arc-radius-integer_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 1, "name": "package.word-anchor-open", "relativePath": "broken/package.word-anchor-open.docx", "sha256": "9c0b13c74c82a6fdcb44028fead5c72b7532d257e25e8a7473a2598aa59bafda", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00003__wfv__package.word-anchor-open.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:16:44.644 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41a", "pass": 2, "name": "package.word-anchor-open", "relativePath": "broken/package.word-anchor-open.docx", "sha256": "9c0b13c74c82a6fdcb44028fead5c72b7532d257e25e8a7473a2598aa59bafda", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00003__wfv__package.word-anchor-open.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:29:30.002 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00003__wfv__package.word-anchor-open....)'"]}
{"run": "s41a", "pass": 1, "name": "package.word-anchor-open-repaired", "relativePath": "working/package.word-anchor-open-repaired.docx", "sha256": "f38a49e7a7eb4523b1561d855e2929615ae9f0dbb3573d3471083a030cc1b547", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00002__wfv__package.word-anchor-open-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-anchor-open-repaired_byword.pdf (167209 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 2, "name": "package.word-anchor-open-repaired", "relativePath": "working/package.word-anchor-open-repaired.docx", "sha256": "f38a49e7a7eb4523b1561d855e2929615ae9f0dbb3573d3471083a030cc1b547", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00002__wfv__package.word-anchor-open-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-anchor-open-repaired_byword.pdf (167146 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 1, "name": "package.word-attached-toolbar-utf8", "relativePath": "broken/package.word-attached-toolbar-utf8.docx", "sha256": "b0cf666af937209d4c91305e652eb5216412db6bf83b61aa7c390c59970dc7cb", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00005__wfv__package.word-attached-toolbar-utf8.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:16:57.421 \"Word found unreadable content in 00005__wfv__package.word-attached-toolbar-utf8.docx. Do you want to recover the contents of this document? If you tr"]}
{"run": "s41a", "pass": 2, "name": "package.word-attached-toolbar-utf8", "relativePath": "broken/package.word-attached-toolbar-utf8.docx", "sha256": "b0cf666af937209d4c91305e652eb5216412db6bf83b61aa7c390c59970dc7cb", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00005__wfv__package.word-attached-toolbar-utf8.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:29:34.254 'Word found unreadable content in 00005__wfv__package.word-attached-toolbar-utf8.docx. Do you want t … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:29:35.197 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package.word-attached-too...)\""]}
{"run": "s41a", "pass": 1, "name": "package.word-attached-toolbar-utf8-repaired", "relativePath": "working/package.word-attached-toolbar-utf8-repaired.docx", "sha256": "864227204267541a0ecabc3a72412ec3b19b38b9541d3fd84e6f7916e1dd1c68", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00004__wfv__package.word-attached-toolbar-utf8-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-attached-toolbar-utf8-repaired_byword.pdf (434534 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 2, "name": "package.word-attached-toolbar-utf8-repaired", "relativePath": "working/package.word-attached-toolbar-utf8-repaired.docx", "sha256": "864227204267541a0ecabc3a72412ec3b19b38b9541d3fd84e6f7916e1dd1c68", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00004__wfv__package.word-attached-toolbar-utf8-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-attached-toolbar-utf8-repaired_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 1, "name": "package.word-cell-ends-with-table", "relativePath": "broken/package.word-cell-ends-with-table.docx", "sha256": "c63ee16523e32bfaa8d12d5abfc5a33fcfafa0667c203419099633a259261f21", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00006__wfv__package.word-cell-ends-with-table.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:17:48.915 Microsoft Word, Word found unreadable content in 00006__wfv__package.word-cell-ends-with-table.docx. Do you want to recover the contents of this docum", "2026-10-25 21:17:49.643 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41a", "pass": 2, "name": "package.word-cell-ends-with-table", "relativePath": "broken/package.word-cell-ends-with-table.docx", "sha256": "c63ee16523e32bfaa8d12d5abfc5a33fcfafa0667c203419099633a259261f21", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00006__wfv__package.word-cell-ends-with-table.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:30:24.435 'Word found unreadable content in 00006__wfv__package.word-cell-ends-with-table.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:30:25.066 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__package.word-cell-ends-wi...)\""]}
{"run": "s41a", "pass": 1, "name": "s41a-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:18:27+00:00", "staged": "00007__wfv__s41a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41a", "pass": 2, "name": "s41a-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:30:59+00:00", "staged": "00007__wfv__s41a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 1, "name": "package.word-cell-ends-with-table-repaired", "relativePath": "working/package.word-cell-ends-with-table-repaired.docx", "sha256": "f43be4fc8ad3ba0a1f9322601f114c0e65009e381c84c1973758c0a263a54795", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00000__wfv__package.word-cell-ends-with-table-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-cell-ends-with-table-repaired_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 2, "name": "package.word-cell-ends-with-table-repaired", "relativePath": "working/package.word-cell-ends-with-table-repaired.docx", "sha256": "f43be4fc8ad3ba0a1f9322601f114c0e65009e381c84c1973758c0a263a54795", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00000__wfv__package.word-cell-ends-with-table-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-cell-ends-with-table-repaired_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 1, "name": "package.word-choice-requires-on-descendant", "relativePath": "broken/package.word-choice-requires-on-descendant.docx", "sha256": "a8e728c4107c1487b8c204836e4418d9aad241c452673c6737c3bdfd0ac68920", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00003__wfv__package.word-choice-requires-on-descendant.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:19:08.585 'Word found unreadable content in 00003__wfv__package.word-choice-requires-on-descendant.docx. Do you want to recover the contents of this document? I", "2026-10-25 21:19:09.575 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41b", "pass": 2, "name": "package.word-choice-requires-on-descendant", "relativePath": "broken/package.word-choice-requires-on-descendant.docx", "sha256": "a8e728c4107c1487b8c204836e4418d9aad241c452673c6737c3bdfd0ac68920", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00003__wfv__package.word-choice-requires-on-descendant.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:31:17.671 'Word found unreadable content in 00003__wfv__package.word-choice-requires-on-descendant.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:31:18.729 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__package.word-choice-requi...)\""]}
{"run": "s41b", "pass": 1, "name": "package.word-choice-requires-on-ancestor", "relativePath": "working/package.word-choice-requires-on-ancestor.docx", "sha256": "aa69a3c4b3448b80ced9fb91cdc34985e2199eb441e0d5292e9bf9af6f9e8e04", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00002__wfv__package.word-choice-requires-on-ancestor.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-choice-requires-on-ancestor_byword.pdf (11568 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 2, "name": "package.word-choice-requires-on-ancestor", "relativePath": "working/package.word-choice-requires-on-ancestor.docx", "sha256": "aa69a3c4b3448b80ced9fb91cdc34985e2199eb441e0d5292e9bf9af6f9e8e04", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00002__wfv__package.word-choice-requires-on-ancestor.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-choice-requires-on-ancestor_byword.pdf (11568 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 1, "name": "package.word-choice-requires-undeclared", "relativePath": "broken/package.word-choice-requires-undeclared.docx", "sha256": "f2bdb740a3021200d616c3bd3171226386442ccc81c34830825addea5d0133a7", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00004__wfv__package.word-choice-requires-undeclared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:19:58.309 Microsoft Word, Word found unreadable content in 00004__wfv__package.word-choice-requires-undeclared.docx. Do you want to recover the contents of this"]}
{"run": "s41b", "pass": 2, "name": "package.word-choice-requires-undeclared", "relativePath": "broken/package.word-choice-requires-undeclared.docx", "sha256": "f2bdb740a3021200d616c3bd3171226386442ccc81c34830825addea5d0133a7", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00004__wfv__package.word-choice-requires-undeclared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:32:11.513 \"Word found unreadable content in 00004__wfv__package.word-choice-requires-undeclared.docx. Do you w … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41b", "pass": 1, "name": "package.word-choice-requires-declared", "relativePath": "working/package.word-choice-requires-declared.docx", "sha256": "733d1afd84bd7711be767553ad03da5d3319b5fd5e60f7c17c1eb8f9c2d1c38c", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00001__wfv__package.word-choice-requires-declared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-choice-requires-declared_byword.pdf (11568 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 2, "name": "package.word-choice-requires-declared", "relativePath": "working/package.word-choice-requires-declared.docx", "sha256": "733d1afd84bd7711be767553ad03da5d3319b5fd5e60f7c17c1eb8f9c2d1c38c", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00001__wfv__package.word-choice-requires-declared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-choice-requires-declared_byword.pdf (11568 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 1, "name": "package.word-drawing-extent-negative-cx", "relativePath": "broken/package.word-drawing-extent-negative-cx.docx", "sha256": "de461e33bc71af0bc5a5770b844292b1704ce25467ae498813894c6af61ac39f", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00005__wfv__package.word-drawing-extent-negative-cx.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:20:32.285 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure ther"]}
{"run": "s41b", "pass": 2, "name": "package.word-drawing-extent-negative-cx", "relativePath": "broken/package.word-drawing-extent-negative-cx.docx", "sha256": "de461e33bc71af0bc5a5770b844292b1704ce25467ae498813894c6af61ac39f", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00005__wfv__package.word-drawing-extent-negative-cx.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:32:53.725 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … y converter. (00005__wfv__package.word-drawing-exte...)"]}
{"run": "s41b", "pass": 1, "name": "package.word-drawing-extent-negative-cy", "relativePath": "broken/package.word-drawing-extent-negative-cy.docx", "sha256": "2c44584a5038057a43161b881959a28560ce6da7ad0903d982d3974112ce74fa", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00006__wfv__package.word-drawing-extent-negative-cy.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:21:25.107 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Ma"]}
{"run": "s41b", "pass": 2, "name": "package.word-drawing-extent-negative-cy", "relativePath": "broken/package.word-drawing-extent-negative-cy.docx", "sha256": "2c44584a5038057a43161b881959a28560ce6da7ad0903d982d3974112ce74fa", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00006__wfv__package.word-drawing-extent-negative-cy.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:33:24.235 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00006__wfv__package.word-drawing-exte...)'"]}
{"run": "s41b", "pass": 1, "name": "s41b-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:21:39+00:00", "staged": "00007__wfv__s41b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41b", "pass": 2, "name": "s41b-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:33:24+00:00", "staged": "00007__wfv__s41b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 1, "name": "package.word-drawing-extent-negative", "relativePath": "broken/package.word-drawing-extent-negative.docx", "sha256": "4de3548ff70a39aedd5ef6af9c6938c0bea162e1787da0c5c54c2ad4a927fad0", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00000__wfv__package.word-drawing-extent-negative.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:21:54.900 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permissions for the document or drive.\\n* Make sure ther"]}
{"run": "s41c", "pass": 2, "name": "package.word-drawing-extent-negative", "relativePath": "broken/package.word-drawing-extent-negative.docx", "sha256": "4de3548ff70a39aedd5ef6af9c6938c0bea162e1787da0c5c54c2ad4a927fad0", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00000__wfv__package.word-drawing-extent-negative.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:34:25.804 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00000__wfv__package.word-drawing-exte...)'"]}
{"run": "s41c", "pass": 1, "name": "package.word-drawing-extent-positive", "relativePath": "working/package.word-drawing-extent-positive.docx", "sha256": "9d143beaf514b30b06a824db4d213dacbec6e35e067276841e3bac68d79ebc2b", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00001__wfv__package.word-drawing-extent-positive.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-drawing-extent-positive_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 2, "name": "package.word-drawing-extent-positive", "relativePath": "working/package.word-drawing-extent-positive.docx", "sha256": "9d143beaf514b30b06a824db4d213dacbec6e35e067276841e3bac68d79ebc2b", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00001__wfv__package.word-drawing-extent-positive.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-drawing-extent-positive_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 1, "name": "package.word-duplicate-font-table", "relativePath": "broken/package.word-duplicate-font-table.docx", "sha256": "bfd789dc181637f8bd8007bbab6115d2b949c788cf54f2839c9eb12a80a03324", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00003__wfv__package.word-duplicate-font-table.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:21:59.133 'Word found unreadable content in 00003__wfv__package.word-duplicate-font-table.docx. Do you want to recover the contents of this document? If you tru", "2026-10-25 21:22:00.031 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41c", "pass": 2, "name": "package.word-duplicate-font-table", "relativePath": "broken/package.word-duplicate-font-table.docx", "sha256": "bfd789dc181637f8bd8007bbab6115d2b949c788cf54f2839c9eb12a80a03324", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00003__wfv__package.word-duplicate-font-table.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:34:30.671 'Word found unreadable content in 00003__wfv__package.word-duplicate-font-table.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:34:31.988 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__package.word-duplicate-fo...)\""]}
{"run": "s41c", "pass": 1, "name": "package.word-duplicate-font-table-removed", "relativePath": "working/package.word-duplicate-font-table-removed.docx", "sha256": "c5f6255afe8ce41259862576d6e7670ff1f4613e1fbbda5a3922b271ca6ece77", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00002__wfv__package.word-duplicate-font-table-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-font-table-removed_byword.pdf (174374 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 2, "name": "package.word-duplicate-font-table-removed", "relativePath": "working/package.word-duplicate-font-table-removed.docx", "sha256": "c5f6255afe8ce41259862576d6e7670ff1f4613e1fbbda5a3922b271ca6ece77", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00002__wfv__package.word-duplicate-font-table-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-font-table-removed_byword.pdf (174374 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 1, "name": "package.word-duplicate-settings", "relativePath": "broken/package.word-duplicate-settings.docx", "sha256": "f9ee736e620997bc774eee52ef8efbe28fa0ff8c0fd6234121e1caa941357038", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00005__wfv__package.word-duplicate-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:22:17.224 \"Word found unreadable content in 00005__wfv__package.word-duplicate-settings.docx. Do you want to recover the contents of this document? If you trust"]}
{"run": "s41c", "pass": 2, "name": "package.word-duplicate-settings", "relativePath": "broken/package.word-duplicate-settings.docx", "sha256": "f9ee736e620997bc774eee52ef8efbe28fa0ff8c0fd6234121e1caa941357038", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00005__wfv__package.word-duplicate-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:34:51.534 \"Word found unreadable content in 00005__wfv__package.word-duplicate-settings.docx. Do you want to r … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41c", "pass": 1, "name": "package.word-duplicate-settings-removed", "relativePath": "working/package.word-duplicate-settings-removed.docx", "sha256": "97c58c1673774516b0665a034f225575b68548f9b9659aaf7602b3a3e3efdc24", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00004__wfv__package.word-duplicate-settings-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-settings-removed_byword.pdf (807857 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 2, "name": "package.word-duplicate-settings-removed", "relativePath": "working/package.word-duplicate-settings-removed.docx", "sha256": "97c58c1673774516b0665a034f225575b68548f9b9659aaf7602b3a3e3efdc24", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00004__wfv__package.word-duplicate-settings-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-settings-removed_byword.pdf (807857 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 1, "name": "package.word-duplicate-theme", "relativePath": "broken/package.word-duplicate-theme.docx", "sha256": "52b18dea69dafe56f1242778155d03e1dc419395f21dac99436ff06fc3305758", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00006__wfv__package.word-duplicate-theme.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:23:04.150 'Word found unreadable content in 00006__wfv__package.word-duplicate-theme.docx. Do you want to recover the contents of this document? If you trust th", "2026-10-25 21:23:04.711 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41c", "pass": 2, "name": "package.word-duplicate-theme", "relativePath": "broken/package.word-duplicate-theme.docx", "sha256": "52b18dea69dafe56f1242778155d03e1dc419395f21dac99436ff06fc3305758", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00006__wfv__package.word-duplicate-theme.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:35:40.971 'Word found unreadable content in 00006__wfv__package.word-duplicate-theme.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:35:41.780 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__package.word-duplicate-th...)\""]}
{"run": "s41c", "pass": 1, "name": "s41c-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:23:35+00:00", "staged": "00007__wfv__s41c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41c", "pass": 2, "name": "s41c-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:36:14+00:00", "staged": "00007__wfv__s41c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 1, "name": "package.word-duplicate-theme-removed", "relativePath": "working/package.word-duplicate-theme-removed.docx", "sha256": "c041b18223a6c3d83d5902294918ffec9f5e2a24eba4e6e2c332c7fa164fdd03", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00000__wfv__package.word-duplicate-theme-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-theme-removed_byword.pdf (108739 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 2, "name": "package.word-duplicate-theme-removed", "relativePath": "working/package.word-duplicate-theme-removed.docx", "sha256": "c041b18223a6c3d83d5902294918ffec9f5e2a24eba4e6e2c332c7fa164fdd03", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00000__wfv__package.word-duplicate-theme-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-theme-removed_byword.pdf (108739 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 1, "name": "package.word-duplicate-web-settings", "relativePath": "broken/package.word-duplicate-web-settings.docx", "sha256": "7677b35b052b3b020ed90054122e7f4caefa95c8d747cda2ec33d7c4d7f9d576", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00002__wfv__package.word-duplicate-web-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:24:03.196 'Word found unreadable content in 00002__wfv__package.word-duplicate-web-settings.docx. Do you want to recover the contents of this document? If you t"]}
{"run": "s41d", "pass": 2, "name": "package.word-duplicate-web-settings", "relativePath": "broken/package.word-duplicate-web-settings.docx", "sha256": "7677b35b052b3b020ed90054122e7f4caefa95c8d747cda2ec33d7c4d7f9d576", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00002__wfv__package.word-duplicate-web-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:36:54.047 'Word found unreadable content in 00002__wfv__package.word-duplicate-web-settings.docx. Do you want  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s41d", "pass": 1, "name": "package.word-duplicate-web-settings-removed", "relativePath": "working/package.word-duplicate-web-settings-removed.docx", "sha256": "09c5d3aa41689640a111c9f6b519ac5a8e2c5428691daf5fad2fba428f7b8dd3", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00001__wfv__package.word-duplicate-web-settings-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-web-settings-removed_byword.pdf (1661833 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 2, "name": "package.word-duplicate-web-settings-removed", "relativePath": "working/package.word-duplicate-web-settings-removed.docx", "sha256": "09c5d3aa41689640a111c9f6b519ac5a8e2c5428691daf5fad2fba428f7b8dd3", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00001__wfv__package.word-duplicate-web-settings-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-duplicate-web-settings-removed_byword.pdf (1661833 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 1, "name": "package.word-empty-drawing", "relativePath": "broken/package.word-empty-drawing.docx", "sha256": "f6a4a0e2791d944d857f697900a974faa3efb73ddc4bd7df75d21a43e106598b", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00004__wfv__package.word-empty-drawing.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:24:15.375 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissions for the document or drive. * Make sure there i"]}
{"run": "s41d", "pass": 2, "name": "package.word-empty-drawing", "relativePath": "broken/package.word-empty-drawing.docx", "sha256": "f6a4a0e2791d944d857f697900a974faa3efb73ddc4bd7df75d21a43e106598b", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00004__wfv__package.word-empty-drawing.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:37:05.585 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__package.word-empty-drawin...)'"]}
{"run": "s41d", "pass": 1, "name": "package.word-empty-drawing-removed", "relativePath": "working/package.word-empty-drawing-removed.docx", "sha256": "12ff28d9e5aad5fe817978e79863e084daa123eea9143b6966dbf553886f7b45", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00003__wfv__package.word-empty-drawing-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-empty-drawing-removed_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 2, "name": "package.word-empty-drawing-removed", "relativePath": "working/package.word-empty-drawing-removed.docx", "sha256": "12ff28d9e5aad5fe817978e79863e084daa123eea9143b6966dbf553886f7b45", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00003__wfv__package.word-empty-drawing-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-empty-drawing-removed_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 1, "name": "package.word-footnote-reference-missing", "relativePath": "broken/package.word-footnote-reference-missing.docx", "sha256": "14a04529bcd71e097591a7b068b4e93ce20dcf6a87bd4a3b08bc7a388f332921", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00005__wfv__package.word-footnote-reference-missing.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:26:26.000 'Word found unreadable content in 00005__wfv__package.word-footnote-reference-missing.docx. Do you want to recover the contents of this document? If y"]}
{"run": "s41d", "pass": 2, "name": "package.word-footnote-reference-missing", "relativePath": "broken/package.word-footnote-reference-missing.docx", "sha256": "14a04529bcd71e097591a7b068b4e93ce20dcf6a87bd4a3b08bc7a388f332921", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00005__wfv__package.word-footnote-reference-missing.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:38:19.802 'Word found unreadable content in 00005__wfv__package.word-footnote-reference-missing.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:38:20.358 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package.word-footnote-ref...)\""]}
{"run": "s41d", "pass": 1, "name": "package.word-footnote-reference-present", "relativePath": "working/package.word-footnote-reference-present.docx", "sha256": "9acfb475b6827c78e1c88af2efb074ce4109c171742011b831db25beecaed8f3", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00006__wfv__package.word-footnote-reference-present.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-footnote-reference-present_byword.pdf (9087 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 2, "name": "package.word-footnote-reference-present", "relativePath": "working/package.word-footnote-reference-present.docx", "sha256": "9acfb475b6827c78e1c88af2efb074ce4109c171742011b831db25beecaed8f3", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00006__wfv__package.word-footnote-reference-present.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-footnote-reference-present_byword.pdf (9087 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 1, "name": "s41d-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:26:26+00:00", "staged": "00007__wfv__s41d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41d", "pass": 2, "name": "s41d-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:38:40+00:00", "staged": "00007__wfv__s41d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 1, "name": "package.word-hyperlink-relationship", "relativePath": "broken/package.word-hyperlink-relationship.docx", "sha256": "e22002e4f186a710d0d10084950d7333a892541dffbfca651ae3425dbc299ec3", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00001__wfv__package.word-hyperlink-relationship.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:38:59.919 'Word found unreadable content in 00001__wfv__package.word-hyperlink-relationship.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:39:00.426 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__package.word-hyperlink-re...)\""]}
{"run": "s41e", "pass": 2, "name": "package.word-hyperlink-relationship", "relativePath": "broken/package.word-hyperlink-relationship.docx", "sha256": "e22002e4f186a710d0d10084950d7333a892541dffbfca651ae3425dbc299ec3", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00001__wfv__package.word-hyperlink-relationship.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:41:04.506 'Word found unreadable content in 00001__wfv__package.word-hyperlink-relationship.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:41:05.630 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__package.word-hyperlink-re...)\""]}
{"run": "s41e", "pass": 1, "name": "package.word-hyperlink-relationship-repaired", "relativePath": "working/package.word-hyperlink-relationship-repaired.docx", "sha256": "4478c5ddcdca6f8839950efdebd2646eb12a6e4e7505088ec24846fcfb4a34c7", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00000__wfv__package.word-hyperlink-relationship-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-hyperlink-relationship-repaired_byword.pdf (208806 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 2, "name": "package.word-hyperlink-relationship-repaired", "relativePath": "working/package.word-hyperlink-relationship-repaired.docx", "sha256": "4478c5ddcdca6f8839950efdebd2646eb12a6e4e7505088ec24846fcfb4a34c7", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00000__wfv__package.word-hyperlink-relationship-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-hyperlink-relationship-repaired_byword.pdf (208806 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 1, "name": "package.word-move-from-deleted-text", "relativePath": "broken/package.word-move-from-deleted-text.docx", "sha256": "18d72b31b7f3c6cea734ff5c4f49622a08c7fe04a65c9b0b85ec616297a2d330", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00002__wfv__package.word-move-from-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:39:19.177 \"Word found unreadable content in 00002__wfv__package.word-move-from-deleted-text.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41e", "pass": 2, "name": "package.word-move-from-deleted-text", "relativePath": "broken/package.word-move-from-deleted-text.docx", "sha256": "18d72b31b7f3c6cea734ff5c4f49622a08c7fe04a65c9b0b85ec616297a2d330", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00002__wfv__package.word-move-from-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:43:23.591 'Word found unreadable content in 00002__wfv__package.word-move-from-deleted-text.docx. Do you want  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s41e", "pass": 1, "name": "package.word-move-from-text", "relativePath": "working/package.word-move-from-text.docx", "sha256": "e03de7c960730f8a1321823645963b688e97816c3f9c26f6d502dda887a11e21", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00003__wfv__package.word-move-from-text.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-move-from-text_byword.pdf (7075 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 2, "name": "package.word-move-from-text", "relativePath": "working/package.word-move-from-text.docx", "sha256": "e03de7c960730f8a1321823645963b688e97816c3f9c26f6d502dda887a11e21", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00003__wfv__package.word-move-from-text.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-move-from-text_byword.pdf (7075 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 1, "name": "package.word-numbering-picture-bullet", "relativePath": "broken/package.word-numbering-picture-bullet.docx", "sha256": "4158815657718767242e2a2d7d7dc4aa6043fccbeddf679de2fd76887bbd062a", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00005__wfv__package.word-numbering-picture-bullet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:39:37.892 \"Word found unreadable content in 00005__wfv__package.word-numbering-picture-bullet.docx. Do you wan … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41e", "pass": 2, "name": "package.word-numbering-picture-bullet", "relativePath": "broken/package.word-numbering-picture-bullet.docx", "sha256": "4158815657718767242e2a2d7d7dc4aa6043fccbeddf679de2fd76887bbd062a", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00005__wfv__package.word-numbering-picture-bullet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:43:29.609 \"Word found unreadable content in 00005__wfv__package.word-numbering-picture-bullet.docx. Do you wan … ? If you trust the source of this document, click Yes.\"", "2026-10-25 21:43:29.610 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package.word-numbering-pi...)\""]}
{"run": "s41e", "pass": 1, "name": "package.word-numbering-picture-bullet-removed", "relativePath": "working/package.word-numbering-picture-bullet-removed.docx", "sha256": "09dd6ad583d32301032e3b8d3fdc28c7b2764ecb2f868dbfec419844d5e8d951", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00004__wfv__package.word-numbering-picture-bullet-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-numbering-picture-bullet-removed_byword.pdf (13223 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 2, "name": "package.word-numbering-picture-bullet-removed", "relativePath": "working/package.word-numbering-picture-bullet-removed.docx", "sha256": "09dd6ad583d32301032e3b8d3fdc28c7b2764ecb2f868dbfec419844d5e8d951", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00004__wfv__package.word-numbering-picture-bullet-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-numbering-picture-bullet-removed_byword.pdf (13223 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 1, "name": "package.word-row-without-cell", "relativePath": "broken/package.word-row-without-cell.docx", "sha256": "27e6f7ace511f4b753863f20b315ea35625be34e03f14e5e66813f7cbd7a79d7", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00006__wfv__package.word-row-without-cell.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:40:25.245 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … y converter. (00006__wfv__package.word-row-without-...)"]}
{"run": "s41e", "pass": 2, "name": "package.word-row-without-cell", "relativePath": "broken/package.word-row-without-cell.docx", "sha256": "27e6f7ace511f4b753863f20b315ea35625be34e03f14e5e66813f7cbd7a79d7", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00006__wfv__package.word-row-without-cell.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:44:44.829 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00006__wfv__package.word-row-without-...)'"]}
{"run": "s41e", "pass": 1, "name": "s41e-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:40:41+00:00", "staged": "00007__wfv__s41e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41e", "pass": 2, "name": "s41e-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:44:57+00:00", "staged": "00007__wfv__s41e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 1, "name": "package.word-row-without-cell-repaired", "relativePath": "working/package.word-row-without-cell-repaired.docx", "sha256": "4611517d964637bae3e190a889e573f6b38420ae670066a4f2bd6002f9c802da", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00000__wfv__package.word-row-without-cell-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-row-without-cell-repaired_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 2, "name": "package.word-row-without-cell-repaired", "relativePath": "working/package.word-row-without-cell-repaired.docx", "sha256": "4611517d964637bae3e190a889e573f6b38420ae670066a4f2bd6002f9c802da", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00000__wfv__package.word-row-without-cell-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-row-without-cell-repaired_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 1, "name": "package.word-sdt-id-empty", "relativePath": "broken/package.word-sdt-id-empty.docx", "sha256": "6db54e9f4fb3653525c00db038dbefe8c08f4376babb6398ca57c6f6dddf7c5f", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00002__wfv__package.word-sdt-id-empty.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:45:16.536 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00002__wfv__package.word-sdt-id-empty...)'"]}
{"run": "s41f", "pass": 2, "name": "package.word-sdt-id-empty", "relativePath": "broken/package.word-sdt-id-empty.docx", "sha256": "6db54e9f4fb3653525c00db038dbefe8c08f4376babb6398ca57c6f6dddf7c5f", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00002__wfv__package.word-sdt-id-empty.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:46:24.837 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00002__wfv__package.word-sdt-id-empty...)'"]}
{"run": "s41f", "pass": 1, "name": "package.word-sdt-id-empty-repaired", "relativePath": "working/package.word-sdt-id-empty-repaired.docx", "sha256": "57b2598340c97dd6ac4b2132a970625f652680037fee1aa089b37e1893eafc3f", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00001__wfv__package.word-sdt-id-empty-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-sdt-id-empty-repaired_byword.pdf (721936 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 2, "name": "package.word-sdt-id-empty-repaired", "relativePath": "working/package.word-sdt-id-empty-repaired.docx", "sha256": "57b2598340c97dd6ac4b2132a970625f652680037fee1aa089b37e1893eafc3f", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00001__wfv__package.word-sdt-id-empty-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-sdt-id-empty-repaired_byword.pdf (721936 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 1, "name": "package.word-text-contains-paragraph", "relativePath": "broken/package.word-text-contains-paragraph.docx", "sha256": "f494c423cca2db7e65028c7614b875c36ea82b021327d689ecf43e071a1d0f6e", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00004__wfv__package.word-text-contains-paragraph.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:45:22.292 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__package.word-text-contain...)'"]}
{"run": "s41f", "pass": 2, "name": "package.word-text-contains-paragraph", "relativePath": "broken/package.word-text-contains-paragraph.docx", "sha256": "f494c423cca2db7e65028c7614b875c36ea82b021327d689ecf43e071a1d0f6e", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00004__wfv__package.word-text-contains-paragraph.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 21:46:29.088 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__package.word-text-contain...)'"]}
{"run": "s41f", "pass": 1, "name": "package.word-text-contains-paragraph-lifted", "relativePath": "working/package.word-text-contains-paragraph-lifted.docx", "sha256": "4e6e9576e2afaf61bce31915e4f2a98519d958d18670dc72fffcb089bbb03d04", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00003__wfv__package.word-text-contains-paragraph-lifted.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-text-contains-paragraph-lifted_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 2, "name": "package.word-text-contains-paragraph-lifted", "relativePath": "working/package.word-text-contains-paragraph-lifted.docx", "sha256": "4e6e9576e2afaf61bce31915e4f2a98519d958d18670dc72fffcb089bbb03d04", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00003__wfv__package.word-text-contains-paragraph-lifted.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-text-contains-paragraph-lifted_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 1, "name": "package.word-textbox-choice-deleted-text", "relativePath": "broken/package.word-textbox-choice-deleted-text.docx", "sha256": "4b0a74cbc918f39b944254ffb360b063bf1a26d77586cd748943cbd0dc5c0918", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00005__wfv__package.word-textbox-choice-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:45:29.489 'Word found unreadable content in 00005__wfv__package.word-textbox-choice-deleted-text.docx. Do you  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:45:30.092 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package.word-textbox-choi...)\""]}
{"run": "s41f", "pass": 2, "name": "package.word-textbox-choice-deleted-text", "relativePath": "broken/package.word-textbox-choice-deleted-text.docx", "sha256": "4b0a74cbc918f39b944254ffb360b063bf1a26d77586cd748943cbd0dc5c0918", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00005__wfv__package.word-textbox-choice-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:46:33.272 'Word found unreadable content in 00005__wfv__package.word-textbox-choice-deleted-text.docx. Do you  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:46:34.127 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package.word-textbox-choi...)\""]}
{"run": "s41f", "pass": 1, "name": "package.word-textbox-fallback-deleted-text", "relativePath": "working/package.word-textbox-fallback-deleted-text.docx", "sha256": "13e0bbd7a9dbb62232f8e255562fd67924b0ce2a500676cd75cffb7fd9da7cad", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00006__wfv__package.word-textbox-fallback-deleted-text.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-fallback-deleted-text_byword.pdf (147345 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 2, "name": "package.word-textbox-fallback-deleted-text", "relativePath": "working/package.word-textbox-fallback-deleted-text.docx", "sha256": "13e0bbd7a9dbb62232f8e255562fd67924b0ce2a500676cd75cffb7fd9da7cad", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00006__wfv__package.word-textbox-fallback-deleted-text.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-fallback-deleted-text_byword.pdf (147345 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 1, "name": "s41f-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:46:08+00:00", "staged": "00007__wfv__s41f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41f", "pass": 2, "name": "s41f-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:46:50+00:00", "staged": "00007__wfv__s41f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-deleted-instruction", "relativePath": "broken/package.word-textbox-deleted-instruction.docx", "sha256": "9e517b0313071113182173ecee2e0004a15b6dc970d74fdfd3b2efa2bf2ff26f", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00000__wfv__package.word-textbox-deleted-instruction.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:47:06.937 'Word found unreadable content in 00000__wfv__package.word-textbox-deleted-instruction.docx. Do you  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:47:07.537 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__package.word-textbox-dele...)\""]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-deleted-instruction", "relativePath": "broken/package.word-textbox-deleted-instruction.docx", "sha256": "9e517b0313071113182173ecee2e0004a15b6dc970d74fdfd3b2efa2bf2ff26f", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00000__wfv__package.word-textbox-deleted-instruction.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:49:05.138 'Word found unreadable content in 00000__wfv__package.word-textbox-deleted-instruction.docx. Do you  … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:49:05.724 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__package.word-textbox-dele...)\""]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-inner-deletion", "relativePath": "working/package.word-textbox-inner-deletion.docx", "sha256": "27aebeace127c63f47da20f18b915ec3b15613e28e141a054fcf7d65270d393e", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00005__wfv__package.word-textbox-inner-deletion.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-inner-deletion_byword.pdf (23972 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-inner-deletion", "relativePath": "working/package.word-textbox-inner-deletion.docx", "sha256": "27aebeace127c63f47da20f18b915ec3b15613e28e141a054fcf7d65270d393e", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00005__wfv__package.word-textbox-inner-deletion.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-inner-deletion_byword.pdf (23972 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-deleted-text-shape", "relativePath": "broken/package.word-textbox-deleted-text-shape.docx", "sha256": "25d4f44a585a61edf22dd820af9bc274888becb159b5edc473d6e283333f878f", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00003__wfv__package.word-textbox-deleted-text-shape.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:47:24.562 \"Word found unreadable content in 00003__wfv__package.word-textbox-deleted-text-shape.docx. Do you w … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-deleted-text-shape", "relativePath": "broken/package.word-textbox-deleted-text-shape.docx", "sha256": "25d4f44a585a61edf22dd820af9bc274888becb159b5edc473d6e283333f878f", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00003__wfv__package.word-textbox-deleted-text-shape.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:49:22.523 \"Word found unreadable content in 00003__wfv__package.word-textbox-deleted-text-shape.docx. Do you w … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-deleted-text-shape-repaired", "relativePath": "working/package.word-textbox-deleted-text-shape-repaired.docx", "sha256": "e2442d5e2dbea0bb97daa19bb357fc68f375c5dc790f31cf42eec84e24eb3315", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00002__wfv__package.word-textbox-deleted-text-shape-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-deleted-text-shape-repaired_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-deleted-text-shape-repaired", "relativePath": "working/package.word-textbox-deleted-text-shape-repaired.docx", "sha256": "e2442d5e2dbea0bb97daa19bb357fc68f375c5dc790f31cf42eec84e24eb3315", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00002__wfv__package.word-textbox-deleted-text-shape-repaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-deleted-text-shape-repaired_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-deleted-text", "relativePath": "broken/package.word-textbox-deleted-text.docx", "sha256": "b71ae90db9278fc469d2f30bd3be74951566aee1f16dc57ebd1422b22b603bb7", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00004__wfv__package.word-textbox-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:48:13.009 Microsoft Word, Word found unreadable content in 00004__wfv__package.word-textbox-deleted-text.docx. … t? If you trust the source of this document, click Yes.", "2026-10-25 21:48:13.664 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__package.word-textbox-dele...)\""]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-deleted-text", "relativePath": "broken/package.word-textbox-deleted-text.docx", "sha256": "b71ae90db9278fc469d2f30bd3be74951566aee1f16dc57ebd1422b22b603bb7", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00004__wfv__package.word-textbox-deleted-text.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:50:06.290 Microsoft Word, Word found unreadable content in 00004__wfv__package.word-textbox-deleted-text.docx. … t? If you trust the source of this document, click Yes.", "2026-10-25 21:50:06.409 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__package.word-textbox-dele...)'"]}
{"run": "s41g", "pass": 1, "name": "package.word-textbox-deleted-text-removed", "relativePath": "working/package.word-textbox-deleted-text-removed.docx", "sha256": "43dcec487eecd5458865e53825f815ea6d693ebc7dd6078eca424a7ca9d3adb6", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00001__wfv__package.word-textbox-deleted-text-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-deleted-text-removed_byword.pdf (6763 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 2, "name": "package.word-textbox-deleted-text-removed", "relativePath": "working/package.word-textbox-deleted-text-removed.docx", "sha256": "43dcec487eecd5458865e53825f815ea6d693ebc7dd6078eca424a7ca9d3adb6", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00001__wfv__package.word-textbox-deleted-text-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-textbox-deleted-text-removed_byword.pdf (6763 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 1, "name": "package.word-undeclared-part", "relativePath": "broken/package.word-undeclared-part.docx", "sha256": "cafddc356260ee3c0be45d73252e833f8f2d052189fa1b6051857df10f926730", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00006__wfv__package.word-undeclared-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:48:30.296 \"Word found unreadable content in 00006__wfv__package.word-undeclared-part.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\"", "2026-10-25 21:48:46.172 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__package.word-undeclared-p...)\""]}
{"run": "s41g", "pass": 2, "name": "package.word-undeclared-part", "relativePath": "broken/package.word-undeclared-part.docx", "sha256": "cafddc356260ee3c0be45d73252e833f8f2d052189fa1b6051857df10f926730", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00006__wfv__package.word-undeclared-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:50:12.157 \"Word found unreadable content in 00006__wfv__package.word-undeclared-part.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\"", "2026-10-25 21:50:12.157 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__package.word-undeclared-p...)\""]}
{"run": "s41g", "pass": 1, "name": "s41g-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:48:46+00:00", "staged": "00007__wfv__s41g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41g", "pass": 2, "name": "s41g-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:50:12+00:00", "staged": "00007__wfv__s41g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 1, "name": "package.word-undeclared-part-removed", "relativePath": "working/package.word-undeclared-part-removed.docx", "sha256": "242448a0186ae5f8d2ac92618a5fdb4cf49c0dc714afd89f5f0bc1e1dec9df70", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00000__wfv__package.word-undeclared-part-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-undeclared-part-removed_byword.pdf (131085 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 2, "name": "package.word-undeclared-part-removed", "relativePath": "working/package.word-undeclared-part-removed.docx", "sha256": "242448a0186ae5f8d2ac92618a5fdb4cf49c0dc714afd89f5f0bc1e1dec9df70", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00000__wfv__package.word-undeclared-part-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.word-undeclared-part-removed_byword.pdf (131085 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 1, "name": "package.zip-bytes-after-eocd", "relativePath": "broken/package.zip-bytes-after-eocd.docx", "sha256": "3242542fbdde12549e54e4e721104a297d0293e7a79faf6c2948dfe910ae61d8", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00001__wfv__package.zip-bytes-after-eocd.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:50:42.154 'Word found unreadable content in 00001__wfv__package.zip-bytes-after-eocd.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-25 21:50:42.745 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__package.zip-bytes-after-e...)\""]}
{"run": "s41h", "pass": 2, "name": "package.zip-bytes-after-eocd", "relativePath": "broken/package.zip-bytes-after-eocd.docx", "sha256": "3242542fbdde12549e54e4e721104a297d0293e7a79faf6c2948dfe910ae61d8", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00001__wfv__package.zip-bytes-after-eocd.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:51:46.058 \"Word found unreadable content in 00001__wfv__package.zip-bytes-after-eocd.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41h", "pass": 1, "name": "package.zip-no-bytes-after-eocd", "relativePath": "working/package.zip-no-bytes-after-eocd.docx", "sha256": "77d15a55769074cf87248d9277a90411cb5fce557ba6bf3bec9facd749d8d33e", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00006__wfv__package.zip-no-bytes-after-eocd.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-no-bytes-after-eocd_byword.pdf (410656 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 2, "name": "package.zip-no-bytes-after-eocd", "relativePath": "working/package.zip-no-bytes-after-eocd.docx", "sha256": "77d15a55769074cf87248d9277a90411cb5fce557ba6bf3bec9facd749d8d33e", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00006__wfv__package.zip-no-bytes-after-eocd.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-no-bytes-after-eocd_byword.pdf (410656 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 1, "name": "package.zip-concatenated-copy", "relativePath": "broken/package.zip-concatenated-copy.docx", "sha256": "8ab8b602264794246110ec52c2d37e6789e1c9d002f870fbad8eeccd08fa1645", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00003__wfv__package.zip-concatenated-copy.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:50:59.275 \"Word found unreadable content in 00003__wfv__package.zip-concatenated-copy.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41h", "pass": 2, "name": "package.zip-concatenated-copy", "relativePath": "broken/package.zip-concatenated-copy.docx", "sha256": "8ab8b602264794246110ec52c2d37e6789e1c9d002f870fbad8eeccd08fa1645", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00003__wfv__package.zip-concatenated-copy.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:52:02.725 \"Word found unreadable content in 00003__wfv__package.zip-concatenated-copy.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41h", "pass": 1, "name": "package.zip-concatenated-copy-removed", "relativePath": "working/package.zip-concatenated-copy-removed.docx", "sha256": "f0e727413740038c4d3c80885aba007cfc26e4b1fb5e98ca2ffa66bfb9177f10", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00002__wfv__package.zip-concatenated-copy-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-concatenated-copy-removed_byword.pdf (58913 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 2, "name": "package.zip-concatenated-copy-removed", "relativePath": "working/package.zip-concatenated-copy-removed.docx", "sha256": "f0e727413740038c4d3c80885aba007cfc26e4b1fb5e98ca2ffa66bfb9177f10", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00002__wfv__package.zip-concatenated-copy-removed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-concatenated-copy-removed_byword.pdf (58913 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 1, "name": "package.zip-eocd-comment-overrun", "relativePath": "broken/package.zip-eocd-comment-overrun.docx", "sha256": "51f7d2c2f525146656070173e327fb37aad5b534b3096f4d25dc72e6b22aa692", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00005__wfv__package.zip-eocd-comment-overrun.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:51:11.875 \"Word found unreadable content in 00005__wfv__package.zip-eocd-comment-overrun.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41h", "pass": 2, "name": "package.zip-eocd-comment-overrun", "relativePath": "broken/package.zip-eocd-comment-overrun.docx", "sha256": "51f7d2c2f525146656070173e327fb37aad5b534b3096f4d25dc72e6b22aa692", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00005__wfv__package.zip-eocd-comment-overrun.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 21:52:15.227 \"Word found unreadable content in 00005__wfv__package.zip-eocd-comment-overrun.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s41h", "pass": 1, "name": "package.zip-eocd-comment-declared", "relativePath": "working/package.zip-eocd-comment-declared.docx", "sha256": "4ef5194f3cfbd1f0706eeeeede24e6943f86b5d26c6c6a30e12a67485bec1979", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00004__wfv__package.zip-eocd-comment-declared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-eocd-comment-declared_byword.pdf (91376 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 2, "name": "package.zip-eocd-comment-declared", "relativePath": "working/package.zip-eocd-comment-declared.docx", "sha256": "4ef5194f3cfbd1f0706eeeeede24e6943f86b5d26c6c6a30e12a67485bec1979", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00004__wfv__package.zip-eocd-comment-declared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package.zip-eocd-comment-declared_byword.pdf (91376 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 1, "name": "s41h-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:51:13+00:00", "staged": "00007__wfv__s41h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s41h", "pass": 2, "name": "s41h-control-minimal", "relativePath": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T01:52:16+00:00", "staged": "00007__wfv__s41h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s41h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 41 staging, log check, cross-check and manifest scripts</summary>

`build.py`:

```python
"""Stage the 56 never-probed package fixtures for Word session 41.

Bytes come from git (wfv/release-deadline), never from a working tree, and are
checked against the sha256 recorded in .scratch/pin-136/verdicts.json. Pairs stay
adjacent; each chunk holds 7 fixtures plus a known-clean control queued last.
"""
import hashlib
import json
import shutil
import subprocess
from pathlib import Path

REPO = Path("/Users/arthrod/temp/T/docx-validate")
ROOT = REPO / ".scratch/word-probes"
REF = "wfv/release-deadline"
verdicts = json.loads((REPO / ".scratch/pin-136/verdicts.json").read_text())
by_path = {v["relativePath"]: v for v in verdicts}

pairs = [
    ["broken/package.drawing-arc-radius.docx", "working/package.drawing-arc-radius-integer.docx"],
    ["broken/package.word-anchor-open.docx", "working/package.word-anchor-open-repaired.docx"],
    ["broken/package.word-attached-toolbar-utf8.docx", "working/package.word-attached-toolbar-utf8-repaired.docx"],
    ["broken/package.word-cell-ends-with-table.docx", "working/package.word-cell-ends-with-table-repaired.docx"],
    ["broken/package.word-choice-requires-on-descendant.docx", "working/package.word-choice-requires-on-ancestor.docx"],
    ["broken/package.word-choice-requires-undeclared.docx", "working/package.word-choice-requires-declared.docx"],
    ["broken/package.word-drawing-extent-negative-cx.docx", "broken/package.word-drawing-extent-negative-cy.docx",
     "broken/package.word-drawing-extent-negative.docx", "working/package.word-drawing-extent-positive.docx"],
    ["broken/package.word-duplicate-font-table.docx", "working/package.word-duplicate-font-table-removed.docx"],
    ["broken/package.word-duplicate-settings.docx", "working/package.word-duplicate-settings-removed.docx"],
    ["broken/package.word-duplicate-theme.docx", "working/package.word-duplicate-theme-removed.docx"],
    ["broken/package.word-duplicate-web-settings.docx", "working/package.word-duplicate-web-settings-removed.docx"],
    ["broken/package.word-empty-drawing.docx", "working/package.word-empty-drawing-removed.docx"],
    ["broken/package.word-footnote-reference-missing.docx", "working/package.word-footnote-reference-present.docx"],
    ["broken/package.word-hyperlink-relationship.docx", "working/package.word-hyperlink-relationship-repaired.docx"],
    ["broken/package.word-move-from-deleted-text.docx", "working/package.word-move-from-text.docx"],
    ["broken/package.word-numbering-picture-bullet.docx", "working/package.word-numbering-picture-bullet-removed.docx"],
    ["broken/package.word-row-without-cell.docx", "working/package.word-row-without-cell-repaired.docx"],
    ["broken/package.word-sdt-id-empty.docx", "working/package.word-sdt-id-empty-repaired.docx"],
    ["broken/package.word-text-contains-paragraph.docx", "working/package.word-text-contains-paragraph-lifted.docx"],
    ["broken/package.word-textbox-choice-deleted-text.docx", "working/package.word-textbox-fallback-deleted-text.docx"],
    ["broken/package.word-textbox-deleted-instruction.docx", "working/package.word-textbox-inner-deletion.docx"],
    ["broken/package.word-textbox-deleted-text-shape.docx", "working/package.word-textbox-deleted-text-shape-repaired.docx"],
    ["broken/package.word-textbox-deleted-text.docx", "working/package.word-textbox-deleted-text-removed.docx"],
    ["broken/package.word-undeclared-part.docx", "working/package.word-undeclared-part-removed.docx"],
    ["broken/package.zip-bytes-after-eocd.docx", "working/package.zip-no-bytes-after-eocd.docx"],
    ["broken/package.zip-concatenated-copy.docx", "working/package.zip-concatenated-copy-removed.docx"],
    ["broken/package.zip-eocd-comment-overrun.docx", "working/package.zip-eocd-comment-declared.docx"],
]
order = [p for pair in pairs for p in pair]
assert len(order) == 56 and len(set(order)) == 56 and set(order) == set(by_path), "pair list must cover the 56 exactly"

control = ROOT / "s40a/src/s40a-control-minimal.docx"
control_sha = hashlib.sha256(control.read_bytes()).hexdigest()
chunks = [order[i:i + 7] for i in range(0, 56, 7)]
for n, chunk in enumerate(chunks):
    label = f"s41{'abcdefgh'[n]}"
    run = ROOT / label
    (run / "src").mkdir(parents=True, exist_ok=False)
    specs = []
    for rel in chunk:
        data = subprocess.run(["git", "-C", str(REPO), "show", f"{REF}:tests/fixtures/{rel}"], capture_output=True, check=True).stdout
        sha = hashlib.sha256(data).hexdigest()
        assert sha == by_path[rel]["sha256"], rel
        name = Path(rel).name
        (run / "src" / name).write_bytes(data)
        v = by_path[rel]
        specs.append({"name": name.removesuffix(".docx"), "relativePath": rel, "file": name, "sha256": sha,
                      "wordValid": {"valid": v["wordValid"]["valid"], "errors": v["wordValid"]["errorCodes"]},
                      "strict": {"valid": v["strict"]["valid"], "errors": v["strict"]["errorCodes"]}})
    cname = f"{label}-control-minimal.docx"
    shutil.copyfile(control, run / "src" / cname)
    specs.append({"name": cname.removesuffix(".docx"), "relativePath": None, "file": cname, "sha256": control_sha,
                  "wordValid": {"valid": True, "errors": []}, "strict": {"valid": True, "errors": []}, "control": True})
    (run / "specimens.jsonl").write_text("".join(json.dumps(s) + "\n" for s in specs))
    print(label, len(specs), [s["file"] for s in specs])
```

`stage_pass2.py`:

```python
"""Give each session-41 chunk a pass2/ run dir with byte-identical src and specimens."""
import hashlib
import shutil
import sys
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
for label in sys.argv[1:]:
    run = ROOT / label
    second = run / "pass2"
    (second / "src").mkdir(parents=True, exist_ok=False)
    for src in sorted((run / "src").iterdir()):
        dst = second / "src" / src.name
        shutil.copyfile(src, dst)
        assert hashlib.sha256(src.read_bytes()).digest() == hashlib.sha256(dst.read_bytes()).digest(), src
    shutil.copyfile(run / "specimens.jsonl", second / "specimens.jsonl")
    print(label, "pass2 staged:", len(list((second / "src").iterdir())), "files")
```

`logcheck.py`:

```python
"""Read each file's Word verdict straight from a word_pdf.py run's own log.

Usage: python3 -I logcheck.py RUN_DIR [RUN_DIR ...]

A run dir holds src/, pdf/manifest.jsonl, word_pdf.log and (optionally) the
outcomes.jsonl that wordpdf_outcomes.py wrote. The verdict here is derived
independently of outcomes.jsonl, from the dialog text the driver logged:

- "Word found unreadable content in <staged>"            -> repair-warning
- "Word experienced an error trying to open ... (<staged>" -> open-error
- any other dialog naming the staged file                  -> other-dialog
- a non-empty PDF and no dialog naming the file            -> clean-open

Staged names are NNNNN__wfv__<file>, NNNNN being the file's index in sorted
order; Word truncates long names, so dialogs are tied to files by that index.
Writes RUN_DIR/logcheck.jsonl and prints one row per file.
"""
import json
import re
import sys
from pathlib import Path

RECORD_START = re.compile(r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d+ \| ")
DIALOG_MARKERS = ("Word said: ", "Microsoft Word says: ", "-- Word window text: ")
STAGED = re.compile(r"(\d{5})__wfv__")
FULL_STAGED = re.compile(r"(\d{5})__wfv__([^\s\"'()]+?\.docx)")


def records(log: str) -> list[str]:
    out: list[str] = []
    for line in log.splitlines():
        if RECORD_START.match(line) or not out:
            out.append(line)
        else:
            out[-1] += "\n" + line
    return out


def dialog_texts(record: str) -> list[str]:
    texts = []
    for marker in DIALOG_MARKERS:
        start = 0
        while (at := record.find(marker, start)) != -1:
            body = record[at + len(marker):]
            end = body.find("\n-- ")
            texts.append(body if end == -1 else body[:end])
            start = at + len(marker)
    return texts


def kind_of(text: str) -> str:
    if "found unreadable content" in text:
        return "repair-warning"
    if "experienced an error trying to open" in text:
        return "open-error"
    if "password" in text.lower():
        return "password-prompt"
    return "other-dialog"


def check(run: Path) -> list[dict]:
    names = sorted(p.name for p in (run / "src").iterdir() if p.suffix == ".docx")
    log = (run / "word_pdf.log").read_text(errors="replace")
    for index, name in FULL_STAGED.findall(log):
        assert names[int(index)] == name, f"{run}: staged index {index} is {name}, sorted order says {names[int(index)]}"
    manifest = {}
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        manifest[row["original_filename"]] = row
    outcomes = {}
    if (run / "outcomes.jsonl").exists():
        for line in (run / "outcomes.jsonl").read_text().splitlines():
            row = json.loads(line)
            outcomes[row["file"]] = row["word"]["outcome"]
    evidence: dict[int, list[tuple[str, str]]] = {i: [] for i in range(len(names))}
    for record in records(log):
        stamp = record[:23]
        for text in dialog_texts(record):
            for index in {int(i) for i in STAGED.findall(text)}:
                flat = " ".join(text.split())
                item = (kind_of(text), f"{stamp} {flat if len(flat) <= 160 else flat[:100] + ' … ' + flat[-55:]}")
                if item[0] not in {k for k, _ in evidence[index]}:
                    evidence[index].append(item)
    rows = []
    for index, name in enumerate(names):
        kinds = [k for k, _ in evidence[index]]
        entry = manifest.get(name, {})
        pdf = Path(entry.get("path_out") or "/nonexistent")
        pdf_ok = entry.get("status") == "ok" and pdf.is_file() and pdf.stat().st_size > 0
        if "repair-warning" in kinds:
            verdict = "repair-warning"
        elif "open-error" in kinds:
            verdict = "open-error"
        elif kinds:
            verdict = kinds[0]
        elif pdf_ok:
            verdict = "clean-open"
        else:
            verdict = "no-evidence"
        conflict = (verdict == "clean-open") != pdf_ok
        rows.append({"file": name, "staged": f"{index:05d}__wfv__{name}", "logVerdict": verdict,
                     "outcomesVerdict": outcomes.get(name), "pdf": pdf_ok, "status": entry.get("status"),
                     "conflict": conflict, "evidence": [e for _, e in evidence[index]]
                     or ([f"PDF {pdf.name} ({pdf.stat().st_size} bytes), no dialog named the file"] if pdf_ok else [])})
    (run / "logcheck.jsonl").write_text("".join(json.dumps(r) + "\n" for r in rows))
    return rows


for arg in sys.argv[1:]:
    run = Path(arg)
    print(f"== {run}")
    for r in check(run):
        flag = "" if r["logVerdict"] == r["outcomesVerdict"] and not r["conflict"] else "  <-- MISMATCH"
        print(f"  {r['file']:<52} log={r['logVerdict']:<15} table={r['outcomesVerdict']!s:<15}{flag}")
        for e in r["evidence"]:
            print(f"      {e}")
```

`compare.py`:

```python
"""Join both passes of every session-41 chunk: log verdicts, table verdicts, validator verdicts."""
import json
from collections import Counter
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
rows, problems = [], []
for label in [f"s41{c}" for c in "abcdefgh"]:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        verdicts = {p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]}
        agreed = len(verdicts) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(p1["logVerdict"]) if agreed else "unknown"
        word_clean = outcome == "clean-open"
        validator_ok = spec["wordValid"]["valid"]
        row = {"chunk": label, "file": name, "relativePath": spec.get("relativePath"), "sha256": spec["sha256"],
               "pass1": p1["logVerdict"], "pass2": p2["logVerdict"], "agreed": agreed, "outcome": outcome,
               "wordValid": validator_ok, "validatorMatchesWord": agreed and validator_ok == word_clean,
               "control": bool(spec.get("control"))}
        rows.append(row)
        if not agreed or not row["validatorMatchesWord"]:
            problems.append(row)
(ROOT / "s41/results.json").write_text(json.dumps(rows, indent=2) + "\n")
fixtures = [r for r in rows if not r["control"]]
print("files:", len(rows), "fixtures:", len(fixtures), "controls:", len(rows) - len(fixtures))
print("both passes + both logs agree:", sum(r["agreed"] for r in rows), "/", len(rows))
print("validator word-valid matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
by = Counter((r["relativePath"] or "control").split("/")[0] + " " + r["outcome"] for r in rows)
for k, v in sorted(by.items()):
    print(f"  {k}: {v}")
print("problems:", json.dumps(problems, indent=1) if problems else "none")
```

`record.py`:

```python
"""Write the session-41 Word observations into the layer-136 manifest.

Broken entries: replace the 'unknown' placeholder pinned in 3308e0a4 (Word had
never been asked, so there is no observation to retire into history).
Working twins: add entries with the validator verdicts of .scratch/pin-136.
observedAt is the end of the confirming second pass (UTC, from pdf/manifest.jsonl).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

REPO = Path("/Users/arthrod/temp/T/docx-validate")
MANIFEST = REPO / ".scratch/wt-136/tests/fixtures-all.manifest.json"
PROBES = REPO / ".scratch/word-probes"
m = json.loads(MANIFEST.read_text())
results = [r for r in json.loads((PROBES / "s41/results.json").read_text()) if not r["control"]]
verdicts = {v["relativePath"]: v for v in json.loads((REPO / ".scratch/pin-136/verdicts.json").read_text())}
by_path = {e["relativePath"]: e for e in m["entries"]}
assert len(results) == 56 and all(r["agreed"] and r["validatorMatchesWord"] for r in results)

def observed_at(chunk: str, file: str) -> str:
    for line in (PROBES / chunk / "pass2/pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            at = datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
            return at.strftime("%Y-%m-%dT%H:%M:%S.000Z")
    raise KeyError(file)

updated = added = 0
for r in results:
    rel, sha = r["relativePath"], r["sha256"]
    assert verdicts[rel]["sha256"] == sha, rel
    word = {"outcome": r["outcome"], "sha256": sha, "observedAt": observed_at(r["chunk"], r["file"]), "wordVersion": "16.115"}
    if rel.startswith("broken/"):
        entry = by_path[rel]
        assert entry["word"] == {"outcome": "unknown", "sha256": sha}, rel
        entry["word"] = word
        updated += 1
    else:
        assert rel.startswith("working/") and rel not in by_path, rel
        v = verdicts[rel]
        m["entries"].append({"relativePath": rel, "strict": v["strict"], "lenient": v["lenient"], "word": word})
        added += 1
assert all(e["relativePath"].isascii() for e in m["entries"])
m["entries"].sort(key=lambda e: e["relativePath"])
m["totalFixtures"] = len(m["entries"])
MANIFEST.write_text(json.dumps(m, indent=4, ensure_ascii=False) + "\n")
print("updated", updated, "added", added, "total", m["totalFixtures"])
```

`control-verdict.mts`:

```ts
// word-valid/strict verdicts of a session-41 control at the wt-136 head, computed as verdicts.mts does.
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
import { validate } from "../../wt-136/src/scripts/office/validate.js";

const file = process.argv[2];
const run = async (profile: "strict" | "word-valid") => {
    const r = await validate(file, { profile });
    const errorCodes = Array.from(
        new Set(
            r.issues
                .filter((i) => i.severity === "error")
                .map((i) => i.code)
                .filter((c): c is string => Boolean(c)),
        ),
    ).sort();
    return { valid: r.valid, errorCodes };
};
const sha256 = createHash("sha256").update(readFileSync(file)).digest("hex");
console.log(JSON.stringify({ file, sha256, wordValid: await run("word-valid"), strict: await run("strict") }));
```

`section.py`:

````python
"""Render the session-41 observations section of docs/plans/evidence/word-probes-2026-10-24.md."""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
verdicts = {v["relativePath"]: v for v in json.loads(Path("/Users/arthrod/temp/T/docx-validate/.scratch/pin-136/verdicts.json").read_text())}
CONTROL = {"wordValid": {"valid": True, "errorCodes": []}, "strict": {"valid": True, "errorCodes": []}}  # control-verdict.mts at c0a244f5

def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{c}`" for c in v["errorCodes"])

def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)

rows, raw = [], []
for label in [f"s41{c}" for c in "abcdefgh"]:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        v = verdicts.get(s["relativePath"], CONTROL)
        times = [run_at(r, s["file"]) for r in runs]
        name = f"`{s['relativePath']}`" if s["relativePath"] else f"`{s['name']}` (control)"
        rows.append(f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | {name} | `{s['sha256'][:16]}` | "
                    f"{checks[0][s['file']]['logVerdict']} | {checks[1][s['file']]['logVerdict']} | {cell(v['wordValid'])} | {cell(v['strict'])} |")
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "relativePath": s["relativePath"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

scripts = ["build.py", "stage_pass2.py", "logcheck.py", "compare.py", "record.py", "control-verdict.mts", "section.py"]
out = ["### Session 41: 01:16Z–01:52Z on 2026-10-26, validator columns at c0a244f5", "",
       "The 56 package fixtures layer 136 pins: the 29 `tests/fixtures/broken/package.*` single-defect specimens and their 27 `tests/fixtures/working/package.*` twins, "
       "in eight chunks of seven with each pair adjacent and a clean control queued last in every chunk "
       "([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Every chunk ran twice, as two separate driver runs of byte-identical copies. "
       "Each run's rows were read twice: from its own Word log (`logcheck.py`, below) and by `wordpdf_outcomes.py`. "
       "A row counts only when both runs and both readings agree, and all 64 do. "
       "The two times in Observed are the ends of the first and second runs. Rows are listed in staging order; the driver opens a chunk's files in name order.", "",
       "| Run | Observed | Fixture | SHA-256 (first 16) | Word, run 1 | Word, run 2 | word-valid at c0a244f5 | strict at c0a244f5 |",
       "| --- | --- | --- | --- | --- | --- | --- | --- |", *rows, "",
       "<details><summary>Raw records, session 41</summary>", "", "```jsonl", *raw, "```", "", "</details>", "",
       "<details><summary>Session 41 staging, log check, cross-check and manifest scripts</summary>", ""]
for name in scripts:
    lang = "ts" if name.endswith(".mts") else "python"
    out += [f"`{name}`:", "", f"```{lang}", (ROOT / "s41" / name).read_text().rstrip("\n"), "```", ""]
out += ["</details>", ""]
(ROOT / "s41/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
````

</details>

### Session 42: 03:40Z–03:53Z on 2026-10-26, validator columns at b6b80433

The stored item names `opc-item-name-refused` reports and the package view refuses (#629), for the kinds no earlier session had probed. Each specimen is `MINIMAL_PARTS` plus one unreferenced, well-formed `<x/>` entry, built with `buildRawZip` (the name verbatim in the local header and the central directory), so the specimens differ only in that entry's stored name. `629-name-control` stores the entry as `word/xtra.xml`, which places a part; `629-dotdot-segment` repeats session 3's `..` finding with the name in both headers. Each chunk ends with session 40's minimal control, queued last ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Every chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. A cell shows both readings when they differ. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 10 of the 11 rows agree. The two times in Observed are the ends of the first and second runs. Rows are listed in builder order; the driver opens a chunk's files in name order.

| Run    | Observed             | Specimen                   | Stored name          | SHA-256 (first 16) | Word, run 1                            | Word, run 2    | Outcome                    | word-valid at b6b80433                                     | strict at b6b80433                                         |
| ------ | -------------------- | -------------------------- | -------------------- | ------------------ | -------------------------------------- | -------------- | -------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `s42a` | 03:43:04Z, 03:46:35Z | `629-leading-slash`        | `/word/xtra.xml`     | `4c7f101c6c0fa210` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42a` | 03:43:04Z, 03:46:35Z | `629-leading-backslash`    | `\word\xtra.xml`     | `04885b3168c91c1d` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42a` | 03:43:04Z, 03:46:35Z | `629-drive-absolute`       | `C:/word/xtra.xml`   | `c1be0d88feea86b9` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42a` | 03:43:04Z, 03:46:35Z | `629-drive-relative`       | `c:xtra.xml`         | `7c7522f74ee0fa25` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42a` | 03:43:04Z, 03:46:35Z | `629-name-control`         | `word/xtra.xml`      | `0c9490aa2479572b` | clean-open                             | clean-open     | clean-open                 | valid                                                      | invalid: `rels-unreferenced`, `xsd-summary`, `xsd-error`   |
| `s42a` | 03:43:04Z, 03:46:35Z | `s42a-control-minimal-end` | none (control)       | `b705a9a7e3509d7e` | clean-open                             | clean-open     | clean-open                 | valid                                                      | valid                                                      |
| `s42b` | 03:49:53Z, 03:53:04Z | `629-empty-segment`        | `word//xtra.xml`     | `3292bc6f8b7283c9` | log: repair-warning; table: open-error | repair-warning | unknown                    | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42b` | 03:49:53Z, 03:53:04Z | `629-dot-segment`          | `word/./xtra.xml`    | `0122205814390852` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42b` | 03:49:53Z, 03:53:04Z | `629-triple-dot-segment`   | `word/.../xtra.xml`  | `86fcea267125659c` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42b` | 03:49:53Z, 03:53:04Z | `629-dotdot-segment`       | `word/a/../xtra.xml` | `4ace2b1f3c7b6dd4` | repair-warning                         | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s42b` | 03:49:53Z, 03:53:04Z | `s42b-control-minimal-end` | none (control)       | `b705a9a7e3509d7e` | clean-open                             | clean-open     | clean-open                 | valid                                                      | valid                                                      |

<details><summary>Raw records, session 42</summary>

```jsonl
{"run": "s42a", "pass": 1, "name": "629-leading-slash", "storedName": "/word/xtra.xml", "sha256": "4c7f101c6c0fa210ec58d617c505c4fe497e1ba76fdb215fcbc3a743c87fa029", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00003__wfv__629-leading-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:43:01.873 \"Word found unreadable content in 00003__wfv__629-leading-slash.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.\""]}
{"run": "s42a", "pass": 2, "name": "629-leading-slash", "storedName": "/word/xtra.xml", "sha256": "4c7f101c6c0fa210ec58d617c505c4fe497e1ba76fdb215fcbc3a743c87fa029", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00003__wfv__629-leading-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:46:11.343 'Word found unreadable content in 00003__wfv__629-leading-slash.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:46:35.327 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00003__wfv__629-leading-slash.docx)\""]}
{"run": "s42a", "pass": 1, "name": "629-leading-backslash", "storedName": "\\word\\xtra.xml", "sha256": "04885b3168c91c1d7159ce37584827896a4908f5f1d05526050d299e665aeaf3", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00002__wfv__629-leading-backslash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:42:07.018 'Word found unreadable content in 00002__wfv__629-leading-backslash.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:42:07.758 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__629-leading-backslash.docx)\""]}
{"run": "s42a", "pass": 2, "name": "629-leading-backslash", "storedName": "\\word\\xtra.xml", "sha256": "04885b3168c91c1d7159ce37584827896a4908f5f1d05526050d299e665aeaf3", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00002__wfv__629-leading-backslash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:45:20.396 Microsoft Word, Word found unreadable content in 00002__wfv__629-leading-backslash.docx. Do you want … t? If you trust the source of this document, click Yes."]}
{"run": "s42a", "pass": 1, "name": "629-drive-absolute", "storedName": "C:/word/xtra.xml", "sha256": "c1be0d88feea86b9c31fbc26522b288d338770d81685b6cd273ed86b2098652c", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00000__wfv__629-drive-absolute.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:41:05.350 'Word found unreadable content in 00000__wfv__629-drive-absolute.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:41:06.071 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00000__wfv__629-drive-absolute.docx)\""]}
{"run": "s42a", "pass": 2, "name": "629-drive-absolute", "storedName": "C:/word/xtra.xml", "sha256": "c1be0d88feea86b9c31fbc26522b288d338770d81685b6cd273ed86b2098652c", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00000__wfv__629-drive-absolute.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:43:35.783 'Word found unreadable content in 00000__wfv__629-drive-absolute.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:43:36.413 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00000__wfv__629-drive-absolute.docx)\""]}
{"run": "s42a", "pass": 1, "name": "629-drive-relative", "storedName": "c:xtra.xml", "sha256": "7c7522f74ee0fa251691bc312d451caea4b30fce35fee457d0ca9c80b444e75d", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00001__wfv__629-drive-relative.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:41:56.881 Microsoft Word, Word found unreadable content in 00001__wfv__629-drive-relative.docx. Do you want to … t? If you trust the source of this document, click Yes.", "2026-10-25 23:42:02.649 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00001__wfv__629-drive-relative.docx)\""]}
{"run": "s42a", "pass": 2, "name": "629-drive-relative", "storedName": "c:xtra.xml", "sha256": "7c7522f74ee0fa251691bc312d451caea4b30fce35fee457d0ca9c80b444e75d", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00001__wfv__629-drive-relative.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:44:28.533 Microsoft Word, Word found unreadable content in 00001__wfv__629-drive-relative.docx. Do you want to … t? If you trust the source of this document, click Yes.", "2026-10-25 23:44:29.274 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00001__wfv__629-drive-relative.docx)\""]}
{"run": "s42a", "pass": 1, "name": "629-name-control", "storedName": "word/xtra.xml", "sha256": "0c9490aa2479572b2c9f942af1885f2f553765b3109e8ed0f0db90c6539300b1", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00004__wfv__629-name-control.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 629-name-control_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s42a", "pass": 2, "name": "629-name-control", "storedName": "word/xtra.xml", "sha256": "0c9490aa2479572b2c9f942af1885f2f553765b3109e8ed0f0db90c6539300b1", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00004__wfv__629-name-control.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 629-name-control_byword.pdf (13400 bytes), no dialog named the file"]}
{"run": "s42a", "pass": 1, "name": "s42a-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T03:43:04+00:00", "staged": "00005__wfv__s42a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s42a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s42a", "pass": 2, "name": "s42a-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T03:46:35+00:00", "staged": "00005__wfv__s42a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s42a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s42b", "pass": 1, "name": "629-empty-segment", "storedName": "word//xtra.xml", "sha256": "3292bc6f8b7283c975254007ed4c5ca336e5def45b1af0560e039609570fd2a3", "observedAt": "2026-10-26T03:49:53+00:00", "staged": "00002__wfv__629-empty-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-25 23:48:23.265 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … ecovery converter. (00002__wfv__629-empty-segment.docx)", "2026-10-25 23:49:52.987 Microsoft Word, Word found unreadable content in 00002__wfv__629-empty-segment.docx. Do you want to  … t? If you trust the source of this document, click Yes."]}
{"run": "s42b", "pass": 2, "name": "629-empty-segment", "storedName": "word//xtra.xml", "sha256": "3292bc6f8b7283c975254007ed4c5ca336e5def45b1af0560e039609570fd2a3", "observedAt": "2026-10-26T03:53:04+00:00", "staged": "00002__wfv__629-empty-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:52:36.040 Microsoft Word, Word found unreadable content in 00002__wfv__629-empty-segment.docx. Do you want to  … t? If you trust the source of this document, click Yes.", "2026-10-25 23:52:36.753 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00002__wfv__629-empty-segment.docx)\""]}
{"run": "s42b", "pass": 1, "name": "629-dot-segment", "storedName": "word/./xtra.xml", "sha256": "012220581439085259d09ed3d0e61ddf0793d7a4ae091280e141fc7117cc4960", "observedAt": "2026-10-26T03:49:53+00:00", "staged": "00000__wfv__629-dot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:46:59.937 'Word found unreadable content in 00000__wfv__629-dot-segment.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:47:00.525 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00000__wfv__629-dot-segment.docx)\""]}
{"run": "s42b", "pass": 2, "name": "629-dot-segment", "storedName": "word/./xtra.xml", "sha256": "012220581439085259d09ed3d0e61ddf0793d7a4ae091280e141fc7117cc4960", "observedAt": "2026-10-26T03:53:04+00:00", "staged": "00000__wfv__629-dot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:50:45.436 'Word found unreadable content in 00000__wfv__629-dot-segment.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:50:46.028 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00000__wfv__629-dot-segment.docx)\""]}
{"run": "s42b", "pass": 1, "name": "629-triple-dot-segment", "storedName": "word/.../xtra.xml", "sha256": "86fcea267125659cf23daf022bf41db6cf74e8efffc3c6591373a3441cde4e75", "observedAt": "2026-10-26T03:49:53+00:00", "staged": "00003__wfv__629-triple-dot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:48:46.006 'Word found unreadable content in 00003__wfv__629-triple-dot-segment.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:48:46.575 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00003__wfv__629-triple-dot-segment.docx)\""]}
{"run": "s42b", "pass": 2, "name": "629-triple-dot-segment", "storedName": "word/.../xtra.xml", "sha256": "86fcea267125659cf23daf022bf41db6cf74e8efffc3c6591373a3441cde4e75", "observedAt": "2026-10-26T03:53:04+00:00", "staged": "00003__wfv__629-triple-dot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:52:49.764 'Word found unreadable content in 00003__wfv__629-triple-dot-segment.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-25 23:52:50.722 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00003__wfv__629-triple-dot-segment.docx)\""]}
{"run": "s42b", "pass": 1, "name": "629-dotdot-segment", "storedName": "word/a/../xtra.xml", "sha256": "4ace2b1f3c7b6dd48418349e0b1b30efd684f5ec9601fd163a4a91fece5607a4", "observedAt": "2026-10-26T03:49:53+00:00", "staged": "00001__wfv__629-dotdot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:49:02.156 \"Word found unreadable content in 00001__wfv__629-dotdot-segment.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\""]}
{"run": "s42b", "pass": 2, "name": "629-dotdot-segment", "storedName": "word/a/../xtra.xml", "sha256": "4ace2b1f3c7b6dd48418349e0b1b30efd684f5ec9601fd163a4a91fece5607a4", "observedAt": "2026-10-26T03:53:04+00:00", "staged": "00001__wfv__629-dotdot-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-25 23:51:30.019 Microsoft Word, Word found unreadable content in 00001__wfv__629-dotdot-segment.docx. Do you want to … t? If you trust the source of this document, click Yes.", "2026-10-25 23:51:44.403 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … very converter.\\n(00001__wfv__629-dotdot-segment.docx)'"]}
{"run": "s42b", "pass": 1, "name": "s42b-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T03:49:53+00:00", "staged": "00004__wfv__s42b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s42b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s42b", "pass": 2, "name": "s42b-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T03:53:04+00:00", "staged": "00004__wfv__s42b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s42b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 42 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s42builder.mts`:

```ts
// Session 42 (2026-10-26): Word's verdict on the stored item names `opc-item-name-refused` (#629) reports and the
// package view refuses, for the kinds no session probed: a leading `/` or `\`, a drive (`C:/…`, `c:…`), and an empty,
// `.` or `...` segment. Each specimen is MINIMAL_PARTS plus one unreferenced, well-formed `<x/>` entry, built with
// buildRawZip (the name verbatim in the local header and the central directory), so the specimens differ only in that
// entry's stored name. `629-name-control` stores it as `word/xtra.xml`, which places a part (session 3 opened
// `foo/xtra.xml` clean). `629-dotdot-segment` repeats session 3's `..` finding with the name in both headers, as the
// known positive. Each chunk ends with the s40a control's exact bytes (MINIMAL_PARTS through JSZip, sha b705a9a7…),
// which Word opened clean in sessions 40 and 41; rebuilding it would change JSZip's entry dates.
// Run from the layer 136 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s42a pnpm exec tsx s42builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { validate } from "./src/scripts/office/validate";
import { MINIMAL_PARTS } from "./tests/support/minimal-docx";
import { buildRawZip } from "./tests/support/raw-zip";

const withExtraEntry = (name: string) => async (): Promise<Uint8Array> =>
    buildRawZip([...Object.entries(MINIMAL_PARTS).map(([part, content]) => ({ name: part, content })), { name, content: "<x/>" }]);
const S40A_CONTROL = "/Users/arthrod/temp/T/docx-validate/.scratch/word-probes/s40a/src/s40a-control-minimal.docx";
const control = async (): Promise<Uint8Array> => {
    const bytes = readFileSync(S40A_CONTROL);
    const sha = createHash("sha256").update(bytes).digest("hex");
    if (!sha.startsWith("b705a9a7e3509d7e")) throw new Error(`s40a control changed: ${sha}`);
    return bytes;
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s42a: [
        ["629-leading-slash", "#629: unreferenced entry stored as `/word/xtra.xml`", withExtraEntry("/word/xtra.xml")],
        ["629-leading-backslash", "#629: unreferenced entry stored as `\\word\\xtra.xml`", withExtraEntry("\\word\\xtra.xml")],
        ["629-drive-absolute", "#629: unreferenced entry stored as `C:/word/xtra.xml`", withExtraEntry("C:/word/xtra.xml")],
        ["629-drive-relative", "#629: unreferenced entry stored as `c:xtra.xml`", withExtraEntry("c:xtra.xml")],
        ["629-name-control", "#629 control: the same entry stored as `word/xtra.xml`", withExtraEntry("word/xtra.xml")],
        ["s42a-control-minimal-end", "control", control],
    ],
    s42b: [
        ["629-empty-segment", "#629: unreferenced entry stored as `word//xtra.xml`", withExtraEntry("word//xtra.xml")],
        ["629-dot-segment", "#629: unreferenced entry stored as `word/./xtra.xml`", withExtraEntry("word/./xtra.xml")],
        ["629-triple-dot-segment", "#629: unreferenced entry stored as `word/.../xtra.xml`", withExtraEntry("word/.../xtra.xml")],
        [
            "629-dotdot-segment",
            "#629 known positive (#411): unreferenced entry stored as `word/a/../xtra.xml`",
            withExtraEntry("word/a/../xtra.xml"),
        ],
        ["s42b-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        control: issue === "control" || name === "629-name-control",
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-42 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in ("s42a", "s42b"):
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["control"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s42/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<34} {r['sha256'][:16]} outcome={r['outcome']:<27} readings={','.join(r['readings'])} word-valid={r['wordValid']} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-42 parts of docs/plans/evidence/word-probes-2026-10-24.md into s42/section.md.

Reads each chunk's specimens.jsonl (validator columns at b6b80433, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s42/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
STORED = {
    "629-leading-slash": "/word/xtra.xml",
    "629-leading-backslash": "\\word\\xtra.xml",
    "629-drive-absolute": "C:/word/xtra.xml",
    "629-drive-relative": "c:xtra.xml",
    "629-name-control": "word/xtra.xml",
    "629-empty-segment": "word//xtra.xml",
    "629-dot-segment": "word/./xtra.xml",
    "629-triple-dot-segment": "word/.../xtra.xml",
    "629-dotdot-segment": "word/a/../xtra.xml",
}
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s42/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw = [], []
for label in ("s42a", "s42b"):
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        stored = f"`{STORED[s['name']]}`" if s["name"] in STORED else "none (control)"
        result = results[(label, s["file"])]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {stored} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "storedName": STORED.get(s["name"]), "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    "### Session 42: 03:40Z–03:53Z on 2026-10-26, validator columns at b6b80433",
    "",
    "The stored item names `opc-item-name-refused` reports and the package view refuses (#629), for the kinds no earlier session "
    "had probed. Each specimen is `MINIMAL_PARTS` plus one unreferenced, well-formed `<x/>` entry, built with `buildRawZip` "
    "(the name verbatim in the local header and the central directory), so the specimens differ only in that entry's stored name. "
    "`629-name-control` stores the entry as `word/xtra.xml`, which places a part; `629-dotdot-segment` repeats session 3's `..` "
    "finding with the name in both headers. Each chunk ends with session 40's minimal control, queued last "
    "([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Every chunk ran twice, as two separate driver runs of "
    "byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. A cell shows both readings when they differ. Outcome is the manifest spelling when both runs and both "
    "readings agree, and `unknown` otherwise; 10 of the 11 rows agree. The two times in Observed are the ends of the first and "
    "second runs. Rows are listed in builder order; the driver opens a chunk's files in name order.",
    "",
    "| Run | Observed | Specimen | Stored name | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at b6b80433 | strict at b6b80433 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 42</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 42 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s42builder.mts", ROOT / "s42builder.mts", "ts"), ("compare.py", ROOT / "s42/compare.py", "python"),
                         ("section.py", ROOT / "s42/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s42/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 43: 06:25Z on 2026-10-26, validator columns at 6473f54b

Settles the empty segment session 42 left `unknown` (#629). The specimen is session 42's `629-empty-segment` (`word//xtra.xml`), copied byte for byte, alone in its chunk so that no other broken file shares Word's batch. The chunk ends with session 40's minimal control, queued last ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; both rows agree. The two times in Observed are the ends of the first and second runs.

| Run    | Observed             | Specimen                   | Stored name      | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 6473f54b                                     | strict at 6473f54b                                         |
| ------ | -------------------- | -------------------------- | ---------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `s43a` | 06:25:23Z, 06:25:52Z | `629-empty-segment`        | `word//xtra.xml` | `3292bc6f8b7283c9` | repair-warning | repair-warning | unreadable-content-warning | invalid: `opc-item-name-refused`, `package-extract-failed` | invalid: `opc-item-name-refused`, `package-extract-failed` |
| `s43a` | 06:25:23Z, 06:25:52Z | `s43a-control-minimal-end` | none (control)   | `b705a9a7e3509d7e` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      |

<details><summary>Raw records, session 43</summary>

```jsonl
{"run": "s43a", "pass": 1, "name": "629-empty-segment", "storedName": "word//xtra.xml", "sha256": "3292bc6f8b7283c975254007ed4c5ca336e5def45b1af0560e039609570fd2a3", "observedAt": "2026-10-26T06:25:23+00:00", "staged": "00000__wfv__629-empty-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 02:25:21.982 'Word found unreadable content in 00000__wfv__629-empty-segment.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-26 02:25:22.586 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00000__wfv__629-empty-segment.docx)\""]}
{"run": "s43a", "pass": 2, "name": "629-empty-segment", "storedName": "word//xtra.xml", "sha256": "3292bc6f8b7283c975254007ed4c5ca336e5def45b1af0560e039609570fd2a3", "observedAt": "2026-10-26T06:25:52+00:00", "staged": "00000__wfv__629-empty-segment.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 02:25:50.927 'Word found unreadable content in 00000__wfv__629-empty-segment.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-26 02:25:51.554 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00000__wfv__629-empty-segment.docx)\""]}
{"run": "s43a", "pass": 1, "name": "s43a-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T06:25:23+00:00", "staged": "00001__wfv__s43a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s43a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s43a", "pass": 2, "name": "s43a-control-minimal-end", "storedName": null, "sha256": "b705a9a7e3509d7e235ef7087c37a80084caf55fcd3e0cf5e8a3888be400acdc", "observedAt": "2026-10-26T06:25:52+00:00", "staged": "00001__wfv__s43a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s43a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 43 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s43builder.mts`:

```ts
// Session 43 (2026-10-26): settle Word's dialog for the empty segment (`word//xtra.xml`), which session 42 left
// `unknown` (it never opened, but run 1's outcomes table read the error that followed the recovery offer). The specimen
// is session 42's exact bytes (sha 3292bc6f…), alone in its chunk so no other broken file shares the batch, and the
// chunk ends with the s40a control's exact bytes (sha b705a9a7…), named to sort last (#671).
// Run from the layer 136 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s43a pnpm exec tsx s43builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { validate } from "./src/scripts/office/validate";

const PROBES = "/Users/arthrod/temp/T/docx-validate/.scratch/word-probes";
const copyOf = (file: string, shaPrefix: string) => async (): Promise<Uint8Array> => {
    const bytes = readFileSync(path.join(PROBES, file));
    const sha = createHash("sha256").update(bytes).digest("hex");
    if (!sha.startsWith(shaPrefix)) throw new Error(`${file} changed: ${sha}`);
    return bytes;
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s43a: [
        [
            "629-empty-segment",
            "#629: unreferenced entry stored as `word//xtra.xml` (session 42's bytes)",
            copyOf("s42b/src/629-empty-segment.docx", "3292bc6f8b7283c9"),
        ],
        ["s43a-control-minimal-end", "control", copyOf("s40a/src/s40a-control-minimal.docx", "b705a9a7e3509d7e")],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        control: issue === "control",
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-43 chunk: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in ("s43a",):
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["control"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s43/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<34} {r['sha256'][:16]} outcome={r['outcome']:<27} readings={','.join(r['readings'])} word-valid={r['wordValid']} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-43 parts of docs/plans/evidence/word-probes-2026-10-24.md into s43/section.md.

Reads each chunk's specimens.jsonl (validator columns at 6473f54b, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s43/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
STORED = {
    "629-leading-slash": "/word/xtra.xml",
    "629-leading-backslash": "\\word\\xtra.xml",
    "629-drive-absolute": "C:/word/xtra.xml",
    "629-drive-relative": "c:xtra.xml",
    "629-name-control": "word/xtra.xml",
    "629-empty-segment": "word//xtra.xml",
    "629-dot-segment": "word/./xtra.xml",
    "629-triple-dot-segment": "word/.../xtra.xml",
    "629-dotdot-segment": "word/a/../xtra.xml",
}
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s43/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw = [], []
for label in ("s43a",):
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        stored = f"`{STORED[s['name']]}`" if s["name"] in STORED else "none (control)"
        result = results[(label, s["file"])]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {stored} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "storedName": STORED.get(s["name"]), "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    "### Session 43: 06:25Z on 2026-10-26, validator columns at 6473f54b",
    "",
    "Settles the empty segment session 42 left `unknown` (#629). The specimen is session 42's `629-empty-segment` "
    "(`word//xtra.xml`), copied byte for byte, alone in its chunk so that no other broken file shares Word's batch. The "
    "chunk ends with session 40's minimal control, queued last "
    "([#671](https://github.com/jandira-tech/docx-validate/issues/671)). It ran twice, as two separate driver runs of "
    "byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    "otherwise; both rows agree. The two times in Observed are the ends of the first and second runs.",
    "",
    "| Run | Observed | Specimen | Stored name | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 6473f54b | strict at 6473f54b |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 43</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 43 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s43builder.mts", ROOT / "s43builder.mts", "ts"), ("compare.py", ROOT / "s43/compare.py", "python"),
                         ("section.py", ROOT / "s43/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s43/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

<details><summary>Probe script</summary>

Run from the repository root as a copy: `node --import tsx ./word-probe.tmp.mts [specimen …]`.

```ts
// Real-Word probes for #388, #392, #396, #397, #351, #398. Run from the stack worktree root as a copy.
import { createHash } from "node:crypto";
import { execSync } from "node:child_process";
import { appendFileSync, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";
import { verifyInWord } from "./src/lib/word-verifier";

const OUT = "/Users/arthrod/temp/T/wfv-scratch/word-probes";
const RESULTS = path.join(OUT, "results.jsonl");
// Interference guard: another session drives Word through word_pdf.py and logs to REDLINE_LOG.
const REDLINE_LOG = "/Users/arthrod/temp/T/fix013w/oracle/redline.log";
const INCONCLUSIVE = path.join(OUT, "results.inconclusive.jsonl");
const logSize = () => {
    try {
        return statSync(REDLINE_LOG).size;
    } catch {
        return -1;
    }
};
const foreignWordDrivers = () => {
    // Match the executable (ucomm), not command-line text: agents' prompts and shells mention osascript.
    const rows = execSync("ps -Ao pid=,ppid=,ucomm=")
        .toString()
        .split("\n")
        .map((l) => l.trim().match(/^(\d+)\s+(\d+)\s+(.*)$/))
        .filter((m): m is RegExpMatchArray => m !== null)
        .map((m) => ({ pid: Number(m[1]), ppid: Number(m[2]), exe: m[3] }));
    const cmds = new Map(
        execSync("ps -Ao pid=,command=")
            .toString()
            .split("\n")
            .map((l) => l.trim().match(/^(\d+)\s+(.*)$/))
            .filter((m): m is RegExpMatchArray => m !== null)
            .map((m) => [Number(m[1]), m[2]]),
    );
    const parent = new Map(rows.map((r) => [r.pid, r.ppid]));
    const mine = (pid: number) => {
        for (let p = pid, i = 0; p > 1 && i < 64; p = parent.get(p) ?? 1, i++) if (p === process.pid) return true;
        return false;
    };
    const driver = (r: { pid: number; exe: string }) =>
        r.exe === "osascript" || (/^python/i.test(r.exe) && /word_pdf|word_redline/.test(cmds.get(r.pid) ?? ""));
    return rows.filter((r) => driver(r) && !mine(r.pid)).map((r) => `${r.pid} ${r.exe} ${(cmds.get(r.pid) ?? "").slice(0, 80)}`);
};
const done = new Set(
    existsSync(RESULTS)
        ? readFileSync(RESULTS, "utf8")
              .trim()
              .split("\n")
              .filter(Boolean)
              .map((l) => JSON.parse(l).name)
        : [],
);

const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const without = (o: Record<string, string | Uint8Array>, k: string) => {
    const { [k]: _, ...r } = o;
    return r;
};
const upperWord = (parts: Record<string, string | Uint8Array>) =>
    Object.fromEntries(Object.entries(parts).map(([k, v]) => [k.startsWith("word/") ? "WORD/" + k.slice(5) : k, v]));
const invalidCt = CT.replace("</Types>", `<Override PartName="/word/x.xml" ContentType="invalid-type"/></Types>`);
const rawZip = async (entries: [string, string | Uint8Array][]) => {
    const z = new JSZip();
    for (const [k, v] of entries) z.file(k, v);
    return z.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
};
const renameInFixture = async (fixture: string, from: string, to: string) => {
    const z = await JSZip.loadAsync(readFileSync(fixture));
    const out = new JSZip();
    for (const [name, f] of Object.entries(z.files)) {
        if (f.dir) continue;
        out.file(name === from ? to : name, await f.async("uint8array"));
    }
    return out.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
};
const DUP_THEME = "tests/fixtures/broken/package.word-duplicate-theme.docx";
const badDoc = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:document`;
const enc = (e: string) => P["word/document.xml"].replace('encoding="UTF-8"', `encoding="${e}"`);

const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const ctSwap = (from: string, to: string) => CT.replace(from, to);
const STYLES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
const MAIN_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
const CORE_CT = "application/vnd.openxmlformats-package.core-properties+xml";
const CORE_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>t</dc:title></cp:coreProperties>`;
const APP_CT = "application/vnd.openxmlformats-officedocument.extended-properties+xml";
const APP_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>Microsoft Office Word</Application></Properties>`;
const withApp = (appXml: string) => ({
    ...P,
    "docProps/app.xml": appXml,
    "_rels/.rels": P["_rels/.rels"].replace(
        "</Relationships>",
        `<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>`,
    ),
    "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/docProps/app.xml" ContentType="${APP_CT}"/></Types>`),
});
const withCore = (coreType: string) => ({
    ...P,
    "docProps/core.xml": CORE_XML,
    "_rels/.rels": P["_rels/.rels"].replace(
        "</Relationships>",
        `<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`,
    ),
    "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/docProps/core.xml" ContentType="${coreType}"/></Types>`),
});
const docH = P["word/document.xml"]
    .replace("<w:document ", `<w:document xmlns:r="${R_NS}" `)
    .replace("<w:r><w:t>Hello</w:t></w:r>", `<w:hyperlink r:id="rId2"><w:r><w:t>Hello</w:t></w:r></w:hyperlink>`);
const relsH = P["word/_rels/document.xml.rels"].replace(
    "</Relationships>",
    `<Relationship Id="rId2" Type="${R_NS}/hyperlink" Target="https://example.com/" TargetMode="External"/></Relationships>`,
);
const renamed = (from: string, to: string, parts: Record<string, string | Uint8Array> = P) =>
    Object.fromEntries(Object.entries(parts).map(([k, v]) => [k === from ? to : k, v]));

const specimens: [string, string, () => Promise<Buffer>][] = [
    ["control-minimal", "control", () => buildDocx(P)],
    // #388
    ["388-rels-zero-byte", "#388", () => buildDocx({ ...P, "_rels/.rels": "" })],
    ["388-rels-truncated", "#388", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].slice(0, 120) })],
    [
        "388-rels-undeclared-prefix",
        "#388",
        () =>
            buildDocx({
                ...P,
                "_rels/.rels": P["_rels/.rels"]
                    .replace("<Relationships ", "<x:Relationships ")
                    .replace("</Relationships>", "</x:Relationships>"),
            }),
    ],
    // #392
    ["392-WORD-folder-clean", "#392", () => buildDocx(upperWord(P))],
    ["392-WORD-folder-malformed-main", "#392", () => buildDocx(upperWord({ ...P, "word/document.xml": badDoc }))],
    ["392-word-folder-malformed-main-control", "#392", () => buildDocx({ ...P, "word/document.xml": badDoc })],
    // #396
    ["396-CT-upper-clean", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": CT })],
    ["396-CT-upper-invalid-type", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": invalidCt })],
    ["396-CT-exact-invalid-type-control", "#396", () => buildDocx({ ...P, "[Content_Types].xml": invalidCt })],
    ["396-CT-upper-malformed", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": CT.slice(0, 150) })],
    // #397
    ["397-encoding-unknown", "#397", () => buildDocx({ ...P, "word/document.xml": enc("X-UNKNOWN-ENCODING") })],
    ["397-encoding-windows-1252-control", "#397", () => buildDocx({ ...P, "word/document.xml": enc("windows-1252") })],
    // #351
    ["351-dup-case-identical", "#351", () => rawZip([...Object.entries(P), ["WORD/document.xml", P["word/document.xml"]]])],
    ["351-dup-case-lower-good-upper-bad", "#351", () => rawZip([...Object.entries(P), ["WORD/document.xml", badDoc]])],
    ["351-dup-case-upper-bad-first", "#351", () => rawZip([["WORD/document.xml", badDoc], ...Object.entries(P)])],
    ["351-dup-stream-good-then-bad", "#351", () => rawZip([...Object.entries(P), ["[CONTENT_TYPES].XML", invalidCt]])],
    ["351-dup-stream-bad-then-good", "#351", () => rawZip([["[CONTENT_TYPES].XML", invalidCt], ...Object.entries(P)])],
    // #398
    [
        "398-RELS-sidecar-clean",
        "#398",
        () =>
            buildDocx({ ...without(P, "word/_rels/document.xml.rels"), "word/_rels/document.xml.RELS": P["word/_rels/document.xml.rels"] }),
    ],
    ["398-dup-theme-control", "#398", async () => readFileSync(DUP_THEME)],
    ["398-dup-theme-RELS", "#398", () => renameInFixture(DUP_THEME, "word/_rels/document.xml.rels", "word/_rels/document.xml.RELS")],
    // word-content-type-invalid scope (Override for an existing part vs a missing one; unused Default)
    [
        "cti-override-existing-styles",
        "cti",
        () => buildDocx({ ...P, "[Content_Types].xml": ctSwap(`ContentType="${STYLES_CT}"`, `ContentType="invalid-${STYLES_CT}"`) }),
    ],
    [
        "cti-override-existing-main",
        "cti",
        () => buildDocx({ ...P, "[Content_Types].xml": ctSwap(`ContentType="${MAIN_CT}"`, `ContentType="invalid-${MAIN_CT}"`) }),
    ],
    ["cti-override-existing-core", "cti", () => buildDocx(withCore(`invalid-${CORE_CT}`))],
    ["cti-override-existing-core-control", "cti", () => buildDocx(withCore(CORE_CT))],
    [
        "cti-default-unused-extension",
        "cti",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    '<Default Extension="rels"',
                    `<Default Extension="foo" ContentType="invalid-type"/><Default Extension="rels"`,
                ),
            }),
    ],
    // #351 escape / backslash duplicates, and the single-spelling controls
    ["351-dup-escape-identical", "#351", () => rawZip([...Object.entries(P), ["word/%73tyles.xml", P["word/styles.xml"]]])],
    ["351-dup-backslash-identical", "#351", () => rawZip([...Object.entries(P), ["word\\document.xml", P["word/document.xml"]]])],
    ["351-escape-only-styles", "#351", () => rawZip(Object.entries(renamed("word/styles.xml", "word/%73tyles.xml")))],
    ["351-backslash-only-main", "#351", () => rawZip(Object.entries(renamed("word/document.xml", "word\\document.xml")))],
    // #398 follow-up: hyperlink resolution through a .RELS sidecar
    ["398-hyperlink-rels-control", "#398", () => buildDocx({ ...P, "word/document.xml": docH, "word/_rels/document.xml.rels": relsH })],
    [
        "398-hyperlink-%72els",
        "#402",
        () =>
            buildDocx({
                ...without({ ...P, "word/document.xml": docH }, "word/_rels/document.xml.rels"),
                "word/_rels/document.xml.%72els": relsH,
            }),
    ],
    [
        "398-hyperlink-RELS",
        "#398",
        () =>
            buildDocx({
                ...without({ ...P, "word/document.xml": docH }, "word/_rels/document.xml.rels"),
                "word/_rels/document.xml.RELS": relsH,
            }),
    ],
    // docProps scope for xml-syntax / xml-encoding (#397 follow-up)
    ["docprops-core-truncated", "docprops", () => buildDocx({ ...withCore(CORE_CT), "docProps/core.xml": CORE_XML.slice(0, 140) })],
    ["docprops-app-control", "docprops", () => buildDocx(withApp(APP_XML))],
    ["docprops-app-truncated", "docprops", () => buildDocx(withApp(APP_XML.slice(0, 140)))],
    [
        "docprops-app-encoding-unknown",
        "docprops",
        () => buildDocx(withApp(APP_XML.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"'))),
    ],
    // Escaped ZIP item names: does Word decode %XX of an unreserved character, or refuse the name itself?
    ["esc-unreferenced-extra-item", "esc", () => rawZip([...Object.entries(P), ["word/%78tra.xml", P["word/styles.xml"]]])],
    ["esc-styles-missing-control", "esc", () => rawZip(Object.entries(without(P, "word/styles.xml")))],
    ["esc-only-main", "esc", () => rawZip(Object.entries(renamed("word/document.xml", "word/%64ocument.xml")))],
    // #397 scope: an unknown declared encoding outside the main part
    [
        "397-encoding-unknown-styles",
        "#397",
        () => buildDocx({ ...P, "word/styles.xml": P["word/styles.xml"].replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') }),
    ],
    [
        "397-encoding-unknown-content-types",
        "#397",
        () => buildDocx({ ...P, "[Content_Types].xml": CT.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') }),
    ],
    [
        "397-encoding-unknown-package-rels",
        "#397",
        () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') }),
    ],
    [
        "397-encoding-unknown-core",
        "#397",
        () =>
            buildDocx(
                Object.fromEntries(
                    Object.entries(withCore(CORE_CT)).map(([k, v]) => [
                        k,
                        k === "docProps/core.xml" ? (v as string).replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') : v,
                    ]),
                ),
            ),
    ],
    // #397: bytes that do not decode in the declared encoding (UTF-8 declared, a lone Latin-1 byte)
    [
        "397-invalid-utf8-bytes",
        "#397",
        async () =>
            buildDocx({
                ...P,
                "word/document.xml": Buffer.concat([
                    Buffer.from(P["word/document.xml"].split("Hello")[0]),
                    Buffer.from([0x48, 0xe9, 0x6c]),
                    Buffer.from(P["word/document.xml"].split("Hello")[1]),
                ]),
            }),
    ],
];

const only = process.argv.slice(2);
for (const [name, issue, make] of specimens) {
    if (only.length && !only.includes(name)) continue;
    if (done.has(name)) {
        console.log(`skip ${name}`);
        continue;
    }
    const bytes = await make();
    const file = path.join(OUT, "specimens", `${name}.docx`);
    writeFileSync(file, bytes);
    const sha = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(file, { profile });
        return { valid: r.valid, errors: r.issues.filter((i) => i.severity === "error").map((i) => `${i.code}@${i.path ?? "-"}`) };
    };
    const wv = await verdict("word-valid");
    const st = await verdict("strict");
    const before = { log: logSize(), drivers: foreignWordDrivers() };
    const word = await verifyInWord(new Uint8Array(bytes));
    const after = { log: logSize(), drivers: foreignWordDrivers() };
    const interference = before.log !== after.log || before.drivers.length > 0 || after.drivers.length > 0 ? { before, after } : undefined;
    const rec = {
        name,
        issue,
        sha256: sha,
        wordValid: wv,
        strict: st,
        word: {
            outcome: word.outcome,
            details: word.details,
            version: word.wordVersion,
            build: word.wordBuild,
            platform: word.platform,
            observedAt: word.observedAt,
            fileSha256: word.fileSha256,
        },
    };
    appendFileSync(interference ? INCONCLUSIVE : RESULTS, JSON.stringify(interference ? { ...rec, interference } : rec) + "\n");
    console.log(
        `${interference ? "INCONCLUSIVE " : ""}${name}: word=${word.outcome} | word-valid=${wv.valid} ${wv.errors.join(",")} | strict=${st.valid}`,
    );
}
```

</details>

<details><summary>Session 3 specimen builder</summary>

The same probe script, extended. Session 3 used its build mode only: `BUILD_DIR=<dir> BUILD_FROM=<first specimen> node --import tsx ./probe.tmp.mts`, run as a copy at the repository root. It writes the specimens and `specimens.jsonl` (hash and verdicts), and opens nothing. JSZip stamps entry times, so a rebuild yields the same shapes under different hashes. The hashes above identify the files Word was given.

<!-- prettier-ignore -->
```ts
// Real-Word probes for #388, #392, #396, #397, #351, #398. Run from the stack worktree root as a copy.
import { createHash } from "node:crypto";
import { execSync } from "node:child_process";
import { appendFileSync, existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";
import { verifyInWord } from "./src/lib/word-verifier";

const OUT = "/Users/arthrod/temp/T/wfv-scratch/word-probes";
const RESULTS = path.join(OUT, "results.jsonl");
// Interference guard: another session drives Word through word_pdf.py and logs to fix013w/oracle*/redline.log
// (the directory name changed between its batches, so watch every one that exists).
const FIX013W = "/Users/arthrod/temp/T/fix013w";
const INCONCLUSIVE = path.join(OUT, "results.inconclusive.jsonl");
const logSize = () => {
  let dirs: string[] = [];
  try { dirs = readdirSync(FIX013W).filter((d) => d.startsWith("oracle")); } catch { /* none */ }
  return dirs.map((d) => { const f = path.join(FIX013W, d, "redline.log"); try { return `${d}:${statSync(f).size}`; } catch { return `${d}:-1`; } }).join(",");
};
const foreignWordDrivers = () => {
  // Match the executable (ucomm), not command-line text: agents' prompts and shells mention osascript.
  const rows = execSync("ps -Ao pid=,ppid=,ucomm=").toString().split("\n").map((l) => l.trim().match(/^(\d+)\s+(\d+)\s+(.*)$/)).filter((m): m is RegExpMatchArray => m !== null).map((m) => ({ pid: Number(m[1]), ppid: Number(m[2]), exe: m[3] }));
  const cmds = new Map(execSync("ps -Ao pid=,command=").toString().split("\n").map((l) => l.trim().match(/^(\d+)\s+(.*)$/)).filter((m): m is RegExpMatchArray => m !== null).map((m) => [Number(m[1]), m[2]]));
  const parent = new Map(rows.map((r) => [r.pid, r.ppid]));
  const mine = (pid: number) => { for (let p = pid, i = 0; p > 1 && i < 64; p = parent.get(p) ?? 1, i++) if (p === process.pid) return true; return false; };
  const driver = (r: { pid: number; exe: string }) => r.exe === "osascript" || (/^python/i.test(r.exe) && /word_pdf|word_redline/.test(cmds.get(r.pid) ?? ""));
  return rows.filter((r) => driver(r) && !mine(r.pid)).map((r) => `${r.pid} ${r.exe} ${(cmds.get(r.pid) ?? "").slice(0, 80)}`);
};
const done = new Set(existsSync(RESULTS) ? readFileSync(RESULTS, "utf8").trim().split("\n").filter(Boolean).map((l) => JSON.parse(l).name) : []);

const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const without = (o: Record<string, string | Uint8Array>, k: string) => { const { [k]: _, ...r } = o; return r; };
const upperWord = (parts: Record<string, string | Uint8Array>) =>
  Object.fromEntries(Object.entries(parts).map(([k, v]) => [k.startsWith("word/") ? "WORD/" + k.slice(5) : k, v]));
const invalidCt = CT.replace("</Types>", `<Override PartName="/word/x.xml" ContentType="invalid-type"/></Types>`);
const rawZip = async (entries: [string, string | Uint8Array][]) => { const z = new JSZip(); for (const [k, v] of entries) z.file(k, v); return z.generateAsync({ type: "nodebuffer", compression: "DEFLATE" }); };
const renameInFixture = async (fixture: string, from: string, to: string) => {
  const z = await JSZip.loadAsync(readFileSync(fixture));
  const out = new JSZip();
  for (const [name, f] of Object.entries(z.files)) { if (f.dir) continue; out.file(name === from ? to : name, await f.async("uint8array")); }
  return out.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
};
const DUP_THEME = "tests/fixtures/broken/package.word-duplicate-theme.docx";
const badDoc = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:document`;
const enc = (e: string) => P["word/document.xml"].replace('encoding="UTF-8"', `encoding="${e}"`);

const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const ctSwap = (from: string, to: string) => CT.replace(from, to);
const STYLES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
const MAIN_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
const CORE_CT = "application/vnd.openxmlformats-package.core-properties+xml";
const CORE_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>t</dc:title></cp:coreProperties>`;
const APP_CT = "application/vnd.openxmlformats-officedocument.extended-properties+xml";
const APP_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>Microsoft Office Word</Application></Properties>`;
const withApp = (appXml: string) => ({
  ...P,
  "docProps/app.xml": appXml,
  "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>`),
  "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/docProps/app.xml" ContentType="${APP_CT}"/></Types>`),
});
const withCore = (coreType: string) => ({
  ...P,
  "docProps/core.xml": CORE_XML,
  "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`),
  "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/docProps/core.xml" ContentType="${coreType}"/></Types>`),
});
const docH = P["word/document.xml"].replace("<w:document ", `<w:document xmlns:r="${R_NS}" `).replace("<w:r><w:t>Hello</w:t></w:r>", `<w:hyperlink r:id="rId2"><w:r><w:t>Hello</w:t></w:r></w:hyperlink>`);
const relsH = P["word/_rels/document.xml.rels"].replace("</Relationships>", `<Relationship Id="rId2" Type="${R_NS}/hyperlink" Target="https://example.com/" TargetMode="External"/></Relationships>`);
const renamed = (from: string, to: string, parts: Record<string, string | Uint8Array> = P) => Object.fromEntries(Object.entries(parts).map(([k, v]) => [k === from ? to : k, v]));

// Session 3 (2026-10-24 ~04:40Z).
// Item names JSZip cannot write (two identical names, an unresolved `..`): write a same-length placeholder, then
// patch its bytes in the local header and the central directory. Exactly two occurrences are required.
const patchNames = (buf: Buffer, pairs: [string, string][]) => {
  for (const [from, to] of pairs) {
    if (from.length !== to.length) throw new Error(`${from} -> ${to}: lengths differ`);
    const f = Buffer.from(from), t = Buffer.from(to);
    let n = 0;
    for (let i = buf.indexOf(f); i !== -1; i = buf.indexOf(f, i + f.length)) { t.copy(buf, i); n += 1; }
    if (n !== 2) throw new Error(`${from}: ${n} occurrences, expected 2`);
  }
  return buf;
};
const CUSTOM_CT = "application/vnd.openxmlformats-officedocument.custom-properties+xml";
const CUSTOM_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="P"><vt:lpwstr>v</vt:lpwstr></property></Properties>`;
const withCustom = (customXml: string) => ({
  ...P,
  "docProps/custom.xml": customXml,
  "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>`),
  "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/docProps/custom.xml" ContentType="${CUSTOM_CT}"/></Types>`),
});
const coreWith = (coreXml: string) => ({ ...withCore(CORE_CT), "docProps/core.xml": coreXml });
// The core-properties part stored under another name, named by its package relationship and its Override.
const coreAt = (name: string, coreXml: string) => ({
  ...P,
  [name]: coreXml,
  "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="${name}"/></Relationships>`),
  "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/${name}" ContentType="${CORE_CT}"/></Types>`),
});
// #410: the main part declared in a real encoding libxml2 cannot decode, with "Hello"'s "e" replaced by one
// correctly encoded non-ASCII character, so a decoder that ignores the label would misread it.
const docIn = (label: string, special: Buffer) => {
  const [a, b] = enc(label).split("Hello");
  return Buffer.concat([Buffer.from(`${a}H`), special, Buffer.from(`llo${b}`)]);
};
const STYLES_OV = `<Override PartName="/word/styles.xml" ContentType="${STYLES_CT}"/>`;
const stylesOverrideNamed = (name: string) => CT.replace(STYLES_OV, `<Override PartName="${name}" ContentType="${STYLES_CT}"/>`);
const extraInvalidOverride = (name: string) => CT.replace("</Types>", `<Override PartName="${name}" ContentType="invalid-x"/></Types>`);
const XML_DEFAULT = `<Default Extension="xml" ContentType="application/xml"/>`;
const extraItem = (name: string) => rawZip([...Object.entries(P), [name, P["word/styles.xml"]]]);

const specimens: [string, string, () => Promise<Buffer>][] = [
  ["control-minimal", "control", () => buildDocx(P)],
  // #388
  ["388-rels-zero-byte", "#388", () => buildDocx({ ...P, "_rels/.rels": "" })],
  ["388-rels-truncated", "#388", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].slice(0, 120) })],
  ["388-rels-undeclared-prefix", "#388", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace("<Relationships ", "<x:Relationships ").replace("</Relationships>", "</x:Relationships>") })],
  // #392
  ["392-WORD-folder-clean", "#392", () => buildDocx(upperWord(P))],
  ["392-WORD-folder-malformed-main", "#392", () => buildDocx(upperWord({ ...P, "word/document.xml": badDoc }))],
  ["392-word-folder-malformed-main-control", "#392", () => buildDocx({ ...P, "word/document.xml": badDoc })],
  // #396
  ["396-CT-upper-clean", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": CT })],
  ["396-CT-upper-invalid-type", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": invalidCt })],
  ["396-CT-exact-invalid-type-control", "#396", () => buildDocx({ ...P, "[Content_Types].xml": invalidCt })],
  ["396-CT-upper-malformed", "#396", () => buildDocx({ ...without(P, "[Content_Types].xml"), "[CONTENT_TYPES].XML": CT.slice(0, 150) })],
  // #397
  ["397-encoding-unknown", "#397", () => buildDocx({ ...P, "word/document.xml": enc("X-UNKNOWN-ENCODING") })],
  ["397-encoding-windows-1252-control", "#397", () => buildDocx({ ...P, "word/document.xml": enc("windows-1252") })],
  // #351
  ["351-dup-case-identical", "#351", () => rawZip([...Object.entries(P), ["WORD/document.xml", P["word/document.xml"]]])],
  ["351-dup-case-lower-good-upper-bad", "#351", () => rawZip([...Object.entries(P), ["WORD/document.xml", badDoc]])],
  ["351-dup-case-upper-bad-first", "#351", () => rawZip([["WORD/document.xml", badDoc], ...Object.entries(P)])],
  ["351-dup-stream-good-then-bad", "#351", () => rawZip([...Object.entries(P), ["[CONTENT_TYPES].XML", invalidCt]])],
  ["351-dup-stream-bad-then-good", "#351", () => rawZip([["[CONTENT_TYPES].XML", invalidCt], ...Object.entries(P)])],
  // #398
  ["398-RELS-sidecar-clean", "#398", () => buildDocx({ ...without(P, "word/_rels/document.xml.rels"), "word/_rels/document.xml.RELS": P["word/_rels/document.xml.rels"] })],
  ["398-dup-theme-control", "#398", async () => readFileSync(DUP_THEME)],
  ["398-dup-theme-RELS", "#398", () => renameInFixture(DUP_THEME, "word/_rels/document.xml.rels", "word/_rels/document.xml.RELS")],
  // word-content-type-invalid scope (Override for an existing part vs a missing one; unused Default)
  ["cti-override-existing-styles", "cti", () => buildDocx({ ...P, "[Content_Types].xml": ctSwap(`ContentType="${STYLES_CT}"`, `ContentType="invalid-${STYLES_CT}"`) })],
  ["cti-override-existing-main", "cti", () => buildDocx({ ...P, "[Content_Types].xml": ctSwap(`ContentType="${MAIN_CT}"`, `ContentType="invalid-${MAIN_CT}"`) })],
  ["cti-override-existing-core", "cti", () => buildDocx(withCore(`invalid-${CORE_CT}`))],
  ["cti-override-existing-core-control", "cti", () => buildDocx(withCore(CORE_CT))],
  ["cti-default-unused-extension", "cti", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("<Default Extension=\"rels\"", `<Default Extension="foo" ContentType="invalid-type"/><Default Extension="rels"`) })],
  // #351 escape / backslash duplicates, and the single-spelling controls
  ["351-dup-escape-identical", "#351", () => rawZip([...Object.entries(P), ["word/%73tyles.xml", P["word/styles.xml"]]])],
  ["351-dup-backslash-identical", "#351", () => rawZip([...Object.entries(P), ["word\\document.xml", P["word/document.xml"]]])],
  ["351-escape-only-styles", "#351", () => rawZip(Object.entries(renamed("word/styles.xml", "word/%73tyles.xml")))],
  ["351-backslash-only-main", "#351", () => rawZip(Object.entries(renamed("word/document.xml", "word\\document.xml")))],
  // #398 follow-up: hyperlink resolution through a .RELS sidecar
  ["398-hyperlink-rels-control", "#398", () => buildDocx({ ...P, "word/document.xml": docH, "word/_rels/document.xml.rels": relsH })],
  ["398-hyperlink-%72els", "#402", () => buildDocx({ ...without({ ...P, "word/document.xml": docH }, "word/_rels/document.xml.rels"), "word/_rels/document.xml.%72els": relsH })],
  ["398-hyperlink-RELS", "#398", () => buildDocx({ ...without({ ...P, "word/document.xml": docH }, "word/_rels/document.xml.rels"), "word/_rels/document.xml.RELS": relsH })],
  // docProps scope for xml-syntax / xml-encoding (#397 follow-up)
  ["docprops-core-truncated", "docprops", () => buildDocx({ ...withCore(CORE_CT), "docProps/core.xml": CORE_XML.slice(0, 140) })],
  ["docprops-app-control", "docprops", () => buildDocx(withApp(APP_XML))],
  ["docprops-app-truncated", "docprops", () => buildDocx(withApp(APP_XML.slice(0, 140)))],
  ["docprops-app-encoding-unknown", "docprops", () => buildDocx(withApp(APP_XML.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"')))],
  // Escaped ZIP item names: does Word decode %XX of an unreserved character, or refuse the name itself?
  ["esc-unreferenced-extra-item", "esc", () => rawZip([...Object.entries(P), ["word/%78tra.xml", P["word/styles.xml"]]])],
  ["esc-styles-missing-control", "esc", () => rawZip(Object.entries(without(P, "word/styles.xml")))],
  ["esc-only-main", "esc", () => rawZip(Object.entries(renamed("word/document.xml", "word/%64ocument.xml")))],
  // #397 scope: an unknown declared encoding outside the main part
  ["397-encoding-unknown-styles", "#397", () => buildDocx({ ...P, "word/styles.xml": P["word/styles.xml"].replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') })],
  ["397-encoding-unknown-content-types", "#397", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') })],
  ["397-encoding-unknown-package-rels", "#397", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') })],
  ["397-encoding-unknown-core", "#397", () => buildDocx(Object.fromEntries(Object.entries(withCore(CORE_CT)).map(([k, v]) => [k, k === "docProps/core.xml" ? (v as string).replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"') : v])))],
  // #397: bytes that do not decode in the declared encoding (UTF-8 declared, a lone Latin-1 byte)
  ["397-invalid-utf8-bytes", "#397", async () => buildDocx({ ...P, "word/document.xml": Buffer.concat([Buffer.from(P["word/document.xml"].split("Hello")[0]), Buffer.from([0x48, 0xe9, 0x6c]), Buffer.from(P["word/document.xml"].split("Hello")[1])]) })],
  // ---- Session 3 ----
  ["s3-control-minimal-start", "control", () => buildDocx(P)],
  // #409: the docProps parts and defects not yet observed (the two app.xml rows repeat session 2's inconclusive ones)
  ["docprops-app-truncated", "#409", () => buildDocx(withApp(APP_XML.slice(0, 140)))],
  ["docprops-app-encoding-unknown", "#409", () => buildDocx(withApp(APP_XML.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"')))],
  ["docprops-app-undeclared-prefix", "#409", () => buildDocx(withApp(APP_XML.replace("<Application>Microsoft Office Word</Application>", "<ax:Application>Microsoft Office Word</ax:Application>")))],
  ["docprops-core-undeclared-prefix", "#409", () => buildDocx(coreWith(CORE_XML.replace("<dc:title>t</dc:title>", "<dcx:title>t</dcx:title>")))],
  ["docprops-custom-control", "#409", () => buildDocx(withCustom(CUSTOM_XML))],
  ["docprops-custom-truncated", "#409", () => buildDocx(withCustom(CUSTOM_XML.slice(0, 160)))],
  ["docprops-custom-undeclared-prefix", "#409", () => buildDocx(withCustom(CUSTOM_XML.replace("<vt:lpwstr>v</vt:lpwstr>", "<vx:lpwstr>v</vx:lpwstr>")))],
  ["docprops-custom-encoding-unknown", "#409", () => buildDocx(withCustom(CUSTOM_XML.replace('encoding="UTF-8"', 'encoding="X-UNKNOWN-ENCODING"')))],
  // #410: real encodings libxml2 has no decoder for
  ["410-macintosh", "#410", async () => buildDocx({ ...P, "word/document.xml": docIn("macintosh", Buffer.from([0x8e])) })],
  ["410-x-mac-cyrillic", "#410", async () => buildDocx({ ...P, "word/document.xml": docIn("x-mac-cyrillic", Buffer.from([0x80])) })],
  ["410-IBM866", "#410", async () => buildDocx({ ...P, "word/document.xml": docIn("IBM866", Buffer.from([0x80])) })],
  ["410-UTF-7", "#410", async () => buildDocx({ ...P, "word/document.xml": docIn("UTF-7", Buffer.from("+AOk-")) })],
  ["410-windows-1252-nonascii-control", "#410", async () => buildDocx({ ...P, "word/document.xml": docIn("windows-1252", Buffer.from([0xe9])) })],
  // #411: two items with the identical name, and a `..` name that JSZip resolves at load
  ["411-identical-valid-valid", "#411", async () => patchNames(await rawZip([...Object.entries(P), ["word/documenX.xml", P["word/document.xml"]]]), [["word/documenX.xml", "word/document.xml"]])],
  ["411-identical-valid-then-malformed", "#411", async () => patchNames(await rawZip([...Object.entries(P), ["word/documenX.xml", badDoc]]), [["word/documenX.xml", "word/document.xml"]])],
  ["411-identical-malformed-then-valid", "#411", async () => patchNames(await rawZip([["word/documenX.xml", badDoc], ...Object.entries(P)]), [["word/documenX.xml", "word/document.xml"]])],
  ["411-dotdot-unreferenced-item", "#411", async () => patchNames(await extraItem("word/a/zzzxtra.xml"), [["word/a/zzzxtra.xml", "word/a/../xtra.xml"]])],
  ["411-dotdot-then-plain-styles", "#411", async () => patchNames(await rawZip([["word/a/zzzstyles.xml", P["word/styles.xml"]], ...Object.entries(P)]), [["word/a/zzzstyles.xml", "word/a/../styles.xml"]])],
  // #414: an Override PartName that is not a valid part name. Valid styles type swapped onto a malformed name
  // (so styles falls back to the xml Default; the removed-Override control isolates that), and an extra
  // invalid-x Override whose malformed name would resolve to the main part.
  ["414-styles-override-removed-control", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(STYLES_OV, "") })],
  ["414-styles-override-dotdot", "#414", () => buildDocx({ ...P, "[Content_Types].xml": stylesOverrideNamed("/word/../word/styles.xml") })],
  ["414-styles-override-query", "#414", () => buildDocx({ ...P, "[Content_Types].xml": stylesOverrideNamed("/word/styles.xml?x=1") })],
  ["414-styles-override-fragment", "#414", () => buildDocx({ ...P, "[Content_Types].xml": stylesOverrideNamed("/word/styles.xml#f") })],
  ["414-styles-override-backslash", "#414", () => buildDocx({ ...P, "[Content_Types].xml": stylesOverrideNamed("/word\\styles.xml") })],
  ["414-invalid-x-dotdot-main", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/../word/document.xml") })],
  ["414-invalid-x-query-main", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/document.xml?x=1") })],
  ["414-invalid-x-fragment-main", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/document.xml#f") })],
  ["414-invalid-x-backslash-main", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word\\document.xml") })],
  // Review V F2: duplicate content-type declarations (System.IO.Packaging throws on a duplicate key)
  ["dupdecl-default-identical", "dupdecl", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(XML_DEFAULT, XML_DEFAULT + XML_DEFAULT) })],
  ["dupdecl-default-case", "dupdecl", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(XML_DEFAULT, `${XML_DEFAULT}<Default Extension="XML" ContentType="application/xml"/>`) })],
  ["dupdecl-override-identical", "dupdecl", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(STYLES_OV, STYLES_OV + STYLES_OV) })],
  ["dupdecl-override-conflicting", "dupdecl", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(STYLES_OV, `${STYLES_OV}<Override PartName="/word/styles.xml" ContentType="application/xml"/>`) })],
  ["dupdecl-override-case", "dupdecl", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace(STYLES_OV, `${STYLES_OV}<Override PartName="/WORD/styles.xml" ContentType="${STYLES_CT}"/>`) })],
  // #408: the unreserved escapes Word has not been shown, on an unreferenced item; a plain-name control, and %20
  // (a space is not unreserved, so [M1.8] permits its escape)
  ["esc-plain-unreferenced-control", "#408", () => extraItem("word/xtra.xml")],
  ["esc-%41-upper-letter", "#408", () => extraItem("word/x%41.xml")],
  ["esc-%30-digit", "#408", () => extraItem("word/x%30.xml")],
  ["esc-%2D-hyphen", "#408", () => extraItem("word/x%2D.xml")],
  ["esc-%2d-hyphen-lowerhex", "#408", () => extraItem("word/x%2d.xml")],
  ["esc-%2E-period", "#408", () => extraItem("word/x%2E.xml")],
  ["esc-%5F-underscore", "#408", () => extraItem("word/x%5F.xml")],
  ["esc-%7E-tilde", "#408", () => extraItem("word/x%7E.xml")],
  ["esc-%20-space-control", "#408", () => extraItem("word/x%20y.xml")],
  ["s3-control-minimal-end", "control", () => buildDocx(P)],
  // CodeRabbit on #383 (word-document-root.ts:105): the package relationship read as a descendant, not a
  // direct child of Relationships. Does Word find a main part that is not a direct child?
  ["rels-main-nested-in-unknown-element", "cr383", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace(/(<Relationship [^>]*\/>)/, `<x:Wrap xmlns:x="urn:x">$1</x:Wrap>`) })],
  ["rels-root-not-relationships", "cr383", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace("<Relationships ", "<Foo ").replace("</Relationships>", "</Foo>") })],
  ["rels-unknown-sibling-control", "cr383", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<x:Extra xmlns:x="urn:x"/></Relationships>`) })],
  // ---- Session 3c ----
  ["s3c-control-minimal", "control", () => buildDocx(P)],
  // Review X F1: the content-types stream spelled with an escape (not a part, so outside [M1.8]'s letter)
  ["ct-stream-missing-control", "rx-f1", () => rawZip(Object.entries(without(P, "[Content_Types].xml")))],
  ["ct-stream-escaped-only", "rx-f1", () => rawZip(Object.entries(renamed("[Content_Types].xml", "[Content_Types].%78ml")))],
  ["ct-stream-escaped-extra", "rx-f1", () => rawZip([...Object.entries(P), ["[Content_Types].%78ml", CT]])],
  // [M1.7]: an escaped "/" or "\" in a stored name (reserved, so outside [M1.8]); nothing reports these today
  ["esc-pct2F-slash-unreferenced", "m17", () => extraItem("word%2Fxtra.xml")],
  ["esc-pct5C-backslash-unreferenced", "m17", () => extraItem("word%5Cxtra.xml")],
  // #409: Word reads a docProps part only through its package relationship. annotations_import_2.docx (clean-open)
  // stores an unreferenced custom.xml with an undeclared prefix; these isolate "unreferenced" in minimal packages.
  ["docprops-custom-unreferenced-undeclared-prefix", "#409", () => buildDocx({ ...withCustom(CUSTOM_XML.replace("<vt:lpwstr>v</vt:lpwstr>", "<vx:lpwstr>v</vx:lpwstr>")), "_rels/.rels": P["_rels/.rels"] })],
  ["docprops-custom-unreferenced-truncated", "#409", () => buildDocx({ ...withCustom(CUSTOM_XML.slice(0, 160)), "_rels/.rels": P["_rels/.rels"] })],
  ["docprops-app-unreferenced-truncated", "#409", () => buildDocx({ ...withApp(APP_XML.slice(0, 140)), "_rels/.rels": P["_rels/.rels"] })],
  // The existing policy blocks xml-syntax anywhere under word/. Is an unreferenced malformed word/ part read at all?
  ["word-unreferenced-malformed-part", "policy", () => buildDocx({ ...P, "word/xtra.xml": P["word/styles.xml"].slice(0, 120) })],
  ["word-unreferenced-wellformed-control", "policy", () => buildDocx({ ...P, "word/xtra.xml": P["word/styles.xml"] })],
  // #409 pass 2: does Word find the core-properties part by its package relationship or by its name?
  ["docprops-core-unreferenced-truncated", "#409", () => buildDocx({ ...withCore(CORE_CT), "docProps/core.xml": CORE_XML.slice(0, 140), "_rels/.rels": P["_rels/.rels"] })],
  ["docprops-core-renamed-truncated", "#409", () => buildDocx(coreAt("props/meta.xml", CORE_XML.slice(0, 140)))],
  ["docprops-core-renamed-control", "#409", () => buildDocx(coreAt("props/meta.xml", CORE_XML))],
  // Review W2 F7 and #380: an empty archive, and a package without its main part, pass word-valid today.
  ["empty-archive", "w2-f7", () => rawZip([])],
  ["main-part-missing", "#380", () => buildDocx(without(P, "word/document.xml"))],
  ["main-relationship-missing", "#380", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace(/<Relationship [^>]*\/officeDocument"[^>]*\/>/, "") })],
  // #414: an invalid-x Override for a part that does not exist opens clean when its PartName is plain (#401).
  // Spelled as a non-part-name, does Word reject the declaration itself, or ignore it?
  ["414-invalid-x-plain-missing-control", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/nothere.xml") })],
  ["414-invalid-x-dotdot-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/../word/nothere.xml") })],
  ["414-invalid-x-query-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/nothere.xml?x=1") })],
  ["414-invalid-x-fragment-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word/nothere.xml#f") })],
  ["414-invalid-x-backslash-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word\\nothere.xml") })],
  // Session 3b's batch could not attribute this control (Word opened a document under another name); observe it again.
  ["rels-unknown-sibling-control", "cr383", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<x:Extra xmlns:x="urn:x"/></Relationships>`) })],
];

// Build-only mode (session 3b, 2026-10-24): write the session-3 specimens, the #383 relationship specimens and
// session-2 calibration rows into BUILD_DIR, with their hashes and validator verdicts, for
// neurotic_docx_bench/scripts/word_pdf.py to open in Word. No Word here. `%` is spelled `pct` in file names.
if (process.env.BUILD_DIR) {
  const dir = process.env.BUILD_DIR;
  const calibration = new Set(["control-minimal", "docprops-core-truncated", "397-encoding-unknown-core", "397-encoding-windows-1252-control", "cti-override-existing-core-control", "351-dup-case-identical", "esc-unreferenced-extra-item", "398-hyperlink-RELS"]);
  // BUILD_FROM picks a later block (e.g. "s3c-control-minimal") and drops the calibration rows.
  const from = process.env.BUILD_FROM;
  if (from) calibration.clear();
  const start = specimens.findIndex(([n]) => n === (from ?? "s3-control-minimal-start"));
  if (start < 0) throw new Error(`no specimen named ${from}`);
  const built = new Set<string>();
  for (const [i, [name, issue, make]] of specimens.entries()) {
    if (built.has(name) || (i < start && !calibration.has(name))) continue;
    built.add(name);
    const bytes = await make();
    const file = `${name.replace(/%/g, "pct")}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
      const r = await validate(path.join(dir, file), { profile });
      return { valid: r.valid, errors: r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`) };
    };
    const row = { name, issue, file, sha256, calibration: i < start, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(`built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} strict=${row.strict.valid}`);
  }
  process.exit(0);
}

const only = process.argv.slice(2);
const ran = new Set<string>();
for (const [name, issue, make] of specimens) {
  if (only.length && !only.includes(name)) continue;
  if (done.has(name)) { console.log(`skip ${name}`); continue; }
  if (ran.has(name)) continue;
  ran.add(name);
  const bytes = await make();
  const file = path.join(OUT, "specimens", `${name}.docx`);
  writeFileSync(file, bytes);
  const sha = createHash("sha256").update(bytes).digest("hex");
  const verdict = async (profile: "word-valid" | "strict") => {
    const r = await validate(file, { profile });
    return { valid: r.valid, errors: r.issues.filter((i) => i.severity === "error").map((i) => `${i.code}@${i.path ?? "-"}`) };
  };
  const wv = await verdict("word-valid");
  const st = await verdict("strict");
  if (process.env.DRY) { console.log(`DRY ${name}: ${sha.slice(0, 16)} | word-valid=${wv.valid} ${wv.errors.join(",")} | strict=${st.valid} ${st.errors.join(",")}`); continue; }
  const before = { log: logSize(), drivers: foreignWordDrivers() };
  const word = await verifyInWord(new Uint8Array(bytes));
  const after = { log: logSize(), drivers: foreignWordDrivers() };
  const interference = before.log !== after.log || before.drivers.length > 0 || after.drivers.length > 0 ? { before, after } : undefined;
  const rec = { name, issue, sha256: sha, wordValid: wv, strict: st, word: { outcome: word.outcome, details: word.details, version: word.wordVersion, build: word.wordBuild, platform: word.platform, observedAt: word.observedAt, fileSha256: word.fileSha256 } };
  appendFileSync(interference ? INCONCLUSIVE : RESULTS, JSON.stringify(interference ? { ...rec, interference } : rec) + "\n");
  console.log(`${interference ? "INCONCLUSIVE " : ""}${name}: word=${word.outcome} | word-valid=${wv.valid} ${wv.errors.join(",")} | strict=${st.valid}`);
}
```

</details>

<details><summary>Session 3 outcome parser</summary>

`python3 wordpdf_outcomes.py <run-dir>` after `uv run --script scripts/word_pdf.py --src <run-dir>/src --out <run-dir>/pdf --log <run-dir>/word_pdf.log --label wfv --no-check-preset --lock-wait 600`, run from the `neurotic_docx_bench` checkout.

```python
"""Turn a neurotic_docx_bench word_pdf.py batch run into per-specimen Word outcomes.

Usage: python3 wordpdf_outcomes.py <run-dir>   (holds specimens.jsonl, src/, word_pdf.log, pdf/manifest.jsonl)

word_pdf.py runs in its default batch mode (one osascript, Word brought forward to answer
alerts) and stages item N as `NNNNN__wfv__<file>`. Attribution is by that staged name in
the dialog text, never by timing; a name Word truncated ("…__wfv__414-invalid-x-fragment-ma...")
is matched by index, else by a unique prefix. Names without the five-digit index belong to an
earlier serial run and are ignored.

  repair-warning  a repair prompt ("Word found unreadable content in <name>") names the file, or
                  word_pdf.py's manifest records "repair prompt declined" for it
  open-error      an "error trying to open the file" alert names the file, with no repair prompt
  clean-open      the manifest says ok (Word opened it and saved a PDF) and no dialog names it
  other           anything else, with the manifest's error and every dialog, for a person to read
"""

from __future__ import annotations

import json
import re
import subprocess
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path

run = Path(sys.argv[1])
ENTRY = re.compile(r"^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \| (\w+)\s*\| (.*)$")
STAGED = re.compile(r"(\d{5})__wfv__([A-Za-z0-9._%+-]+)")

entries: list[tuple[str, str]] = []
for line in (run / "word_pdf.log").read_text(encoding="utf-8").splitlines():
    m = ENTRY.match(line)
    if m:
        entries.append((m.group(1), m.group(3)))
    elif entries:
        stamp, text = entries[-1]
        entries[-1] = (stamp, text + "\n" + line)

offset = timedelta(seconds=-datetime.now().astimezone().utcoffset().total_seconds())


def utc(stamp: str) -> str:
    local = datetime.strptime(stamp, "%Y-%m-%d %H:%M:%S.%f")
    return (local + offset).replace(tzinfo=timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")


specs = [json.loads(l) for l in (run / "specimens.jsonl").read_text().splitlines() if l.strip()]
files = [s["file"] for s in specs]

# Index -> file, from every full (untruncated) staged name in the log.
by_index: dict[str, str] = {}
for _, text in entries:
    for idx, name in STAGED.findall(text):
        name = name.rstrip(".")
        if name in files:
            by_index[idx] = name


def named(text: str) -> set[str]:
    out: set[str] = set()
    for idx, name in STAGED.findall(text):
        full = name.rstrip(".")
        if full in files:
            out.add(full)
        elif idx in by_index:
            out.add(by_index[idx])
        else:
            hits = [f for f in files if f.startswith(full)]
            if len(hits) == 1:
                out.add(hits[0])
    return out


# Only Word's own words: the watchdog's "says:" lines and the "Word said:" text of the alerts
# word_pdf.py answered (its focus nudge and its repair-prompt decline).
said: dict[str, list[tuple[str, str]]] = {f: [] for f in files}
for stamp, text in entries:
    marker = "says:" if "says:" in text else "Word said:" if "Word said:" in text else None
    if marker is None:
        continue
    body = text.split(marker, 1)[1].strip()
    for f in named(body):
        if body not in (b for _, b in said[f]):
            said[f].append((stamp, body))

manifest: dict[str, dict] = {}
mpath = run / "pdf" / "manifest.jsonl"
if mpath.exists():
    for line in mpath.read_text().splitlines():
        if line.strip():
            rec = json.loads(line)
            manifest[rec["original_filename"]] = rec

plist = "/Applications/Microsoft Word.app/Contents/Info.plist"
version = subprocess.run(["defaults", "read", plist, "CFBundleShortVersionString"], capture_output=True, text=True).stdout.strip()
build = subprocess.run(["defaults", "read", plist, "CFBundleVersion"], capture_output=True, text=True).stdout.strip()

out = []
for spec in specs:
    f = spec["file"]
    dialogs = said[f]
    rec_error = str(manifest.get(f, {}).get("error", ""))
    # word_pdf.py's own attribution: it declined a repair prompt it tied to this item.
    repair = any("unreadable content in" in b for _, b in dialogs) or rec_error.startswith("repair prompt declined")
    open_error = any("error trying to open the file" in b for _, b in dialogs)
    rec = manifest.get(f, {})
    status = rec.get("status", "missing")
    if repair:
        outcome = "repair-warning"
    elif open_error:
        outcome = "open-error"
    elif status == "ok" and not dialogs:
        outcome = "clean-open"
    else:
        outcome = "other"
    first = dialogs[0][0] if dialogs else ""
    out.append({
        **spec,
        "word": {
            "outcome": outcome,
            "item": status,
            "error": str(rec.get("error", ""))[:240],
            "dialogs": [b[:240] for _, b in dialogs],
            "observedAt": utc(first) if first else rec.get("run_at", ""),
            "driver": "neurotic_docx_bench/scripts/word_pdf.py (default batch mode, --label wfv)",
            "version": version,
            "build": build,
        },
    })

(run / "outcomes.jsonl").write_text("".join(json.dumps(r) + "\n" for r in out))
for r in out:
    w = r["word"]
    extra = w["error"][:70] if w["outcome"] == "other" else ""
    print(f"{r['name']:50} {w['outcome']:15} word-valid={r['wordValid']['valid']!s:5} strict={r['strict']['valid']!s:5} {extra}")
```

</details>

<details><summary>Sessions 4–14 specimen builders and runner</summary>

Sessions 4 and 5 add these lines to the session 3 builder above. They were built with `BUILD_DIR=<run>/src BUILD_FROM=<first specimen>`, as in session 3:

<!-- prettier-ignore -->
```diff
@@ -112,6 +112,7 @@
 const XML_DEFAULT = `<Default Extension="xml" ContentType="application/xml"/>`;
 const extraItem = (name: string) => rawZip([...Object.entries(P), [name, P["word/styles.xml"]]]);
 
+const spaced = (core: string) => ({ ...withCore(CORE_CT), "docProps/core.xml": core, "_rels/.rels": withCore(CORE_CT)["_rels/.rels"].replace("metadata/core-properties\"", "metadata/core-properties \"") });
 const specimens: [string, string, () => Promise<Buffer>][] = [
   ["control-minimal", "control", () => buildDocx(P)],
   // #388
@@ -263,6 +264,41 @@
   ["414-invalid-x-backslash-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": extraInvalidOverride("/word\\nothere.xml") })],
   // Session 3b's batch could not attribute this control (Word opened a document under another name); observe it again.
   ["rels-unknown-sibling-control", "cr383", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace("</Relationships>", `<x:Extra xmlns:x="urn:x"/></Relationships>`) })],
+  // ---- Session 4 (foreground) ----
+  ["s4-control-minimal", "control", () => buildDocx(P)],
+  // #380: session 3c could not attribute this one (no document, no alert naming it).
+  ["main-relationship-missing", "#380", () => buildDocx({ ...P, "_rels/.rels": P["_rels/.rels"].replace(/<Relationship [^>]*\/officeDocument"[^>]*\/>/, "") })],
+  // #414 with a well-formed content type: is the PartName alone enough, without invalid-x?
+  ["414-xml-plain-missing-control", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/nothere.xml" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-dotdot-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/../word/nothere.xml" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-query-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/nothere.xml?x=1" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-fragment-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/nothere.xml#f" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-backslash-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word\\nothere.xml" ContentType="application/xml"/></Types>`) })],
+  // #408: an unreserved escape in a folder segment, on an unreferenced item.
+  ["esc-folder-segment-unreferenced", "#408", () => extraItem("f%6Fo/xtra.xml")],
+  ["esc-folder-plain-unreferenced-control", "#408", () => extraItem("foo/xtra.xml")],
+  // #437: is an unreferenced malformed part outside word/ ignored too?
+  ["customxml-unreferenced-malformed", "#437", () => buildDocx({ ...P, "customXml/item9.xml": P["word/styles.xml"].slice(0, 120) })],
+  // #433: a foreign element in a part-level relationships part.
+  ["rels-part-level-unknown-sibling", "#433", () => buildDocx({ ...P, "word/_rels/document.xml.rels": P["word/_rels/document.xml.rels"].replace("</Relationships>", `<x:Extra xmlns:x="urn:x"/></Relationships>`) })],
+  ["s4-control-minimal-end", "control", () => buildDocx(P)],
+  // ---- Session 5 (foreground) ----
+  ["s5-control-minimal", "control", () => buildDocx(P)],
+  // #414: part-name shapes Word has not seen yet, each on an application/xml Override of a missing part.
+  ["414-xml-noslash-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="word/nothere.xml" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-emptyseg-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word//nothere.xml" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-trailing-slash-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/nothere.xml/" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-pct2F-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/no%2Fthere.xml" ContentType="application/xml"/></Types>`) })],
+  ["414-xml-pct6F-missing", "#414", () => buildDocx({ ...P, "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/n%6Fthere.xml" ContentType="application/xml"/></Types>`) })],
+  // #437: does Word read a part named only by a relationship of an unknown type?
+  ["437-unknown-type-rel-malformed", "#437", () => buildDocx({ ...P, "word/xtra.xml": P["word/styles.xml"].slice(0, 120), "word/_rels/document.xml.rels": P["word/_rels/document.xml.rels"].replace("</Relationships>", `<Relationship Id="rIdX" Type="urn:x:unknown" Target="xtra.xml"/></Relationships>`) })],
+  ["437-unknown-type-rel-wellformed-control", "#437", () => buildDocx({ ...P, "word/xtra.xml": P["word/styles.xml"], "word/_rels/document.xml.rels": P["word/_rels/document.xml.rels"].replace("</Relationships>", `<Relationship Id="rIdX" Type="urn:x:unknown" Target="xtra.xml"/></Relationships>`) })],
+  // #437: an unreferenced malformed part under word/ that has its own Override.
+  ["437-unreferenced-malformed-override", "#437", () => buildDocx({ ...P, "word/xtra.xml": P["word/styles.xml"].slice(0, 120), "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="/word/xtra.xml" ContentType="application/xml"/></Types>`) })],
+  // Review Z F2: a core-properties relationship Type with a trailing space (xs:anyURI collapses it). Does Word read the part?
+  ["409-type-trailing-space-core-truncated", "#409", () => buildDocx(spaced(CORE_XML.slice(0, 140)))],
+  ["409-type-trailing-space-core-wellformed-control", "#409", () => buildDocx(spaced(CORE_XML))],
+  ["s5-control-minimal-end", "control", () => buildDocx(P)],
 ];
 
 // Build-only mode (session 3b, 2026-10-24): write the session-3 specimens, the #383 relationship specimens and
```

Review Y specimens (session 4d) come from `buildSpecZip`, a raw ZIP writer that sets each name in the central directory and the local header independently. Its extra fields and flag bits are explicit:

<!-- prettier-ignore -->
```ts
// Raw ZIP builder for adversarial specimens. Store-method only.
// Supports per-entry distinct local vs central names, extra fields, and
// arbitrary trailing bytes — the cases the commit under review claims to cover.

const CRC_TABLE = (() => {
    const table = new Uint32Array(256);
    for (let n = 0; n < 256; n += 1) {
        let c = n;
        for (let k = 0; k < 8; k += 1) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
        table[n] = c >>> 0;
    }
    return table;
})();

export const crc32 = (data: Uint8Array): number => {
    let c = 0xffffffff;
    for (const byte of data) c = CRC_TABLE[(c ^ byte) & 0xff]! ^ (c >>> 8);
    return (c ^ 0xffffffff) >>> 0;
};

export interface SpecEntry {
    /** Central-directory name (string is UTF-8 encoded, or nameBytes raw). */
    name?: string;
    nameBytes?: Uint8Array;
    /** Local-header name; defaults to the central name. */
    localName?: string;
    localNameBytes?: Uint8Array;
    /** Central-directory extra field bytes (between name and comment). */
    centralExtra?: Uint8Array;
    /** Local-header extra field bytes. */
    localExtra?: Uint8Array;
    content?: string | Uint8Array;
    utf8?: boolean;
    directory?: boolean;
}

export interface SpecOptions {
    zip64?: boolean;
    /** Bytes appended after the EOCD record. */
    trailing?: Uint8Array;
    /** EOCD comment bytes. */
    comment?: Uint8Array;
    /** Patch hook before return: (bytes, {cdOffset, cdSize, eocdOffset, count}). */
    patch?: (bytes: Buffer, layout: { cdOffset: number; cdSize: number; eocdOffset: number; count: number }) => void;
}

const encoder = new TextEncoder();

export const buildSpecZip = (entries: readonly SpecEntry[], options: SpecOptions = {}): Buffer => {
    const local: Buffer[] = [];
    const central: Buffer[] = [];
    let offset = 0;
    for (const entry of entries) {
        const cnb = entry.nameBytes ?? encoder.encode(entry.name ?? "");
        const lnb = entry.localNameBytes ?? (entry.localName !== undefined ? encoder.encode(entry.localName) : cnb);
        const data = typeof entry.content === "string" ? encoder.encode(entry.content) : (entry.content ?? new Uint8Array());
        const crc = crc32(data);
        const flags = entry.utf8 === true ? 0x0800 : 0;
        const attributes = entry.directory === true ? 0x10 : 0;
        const lex = entry.localExtra ?? new Uint8Array();
        const cex = entry.centralExtra ?? new Uint8Array();

        const lh = Buffer.alloc(30);
        lh.writeUInt32LE(0x04034b50, 0);
        lh.writeUInt16LE(20, 4);
        lh.writeUInt16LE(flags, 6);
        lh.writeUInt32LE(crc, 14);
        lh.writeUInt32LE(data.length, 18);
        lh.writeUInt32LE(data.length, 22);
        lh.writeUInt16LE(lnb.length, 26);
        lh.writeUInt16LE(lex.length, 28);
        local.push(lh, Buffer.from(lnb), Buffer.from(lex), Buffer.from(data));

        const ch = Buffer.alloc(46);
        ch.writeUInt32LE(0x02014b50, 0);
        ch.writeUInt16LE(20, 4);
        ch.writeUInt16LE(20, 6);
        ch.writeUInt16LE(flags, 8);
        ch.writeUInt32LE(crc, 16);
        ch.writeUInt32LE(data.length, 20);
        ch.writeUInt32LE(data.length, 24);
        ch.writeUInt16LE(cnb.length, 28);
        ch.writeUInt16LE(cex.length, 30);
        ch.writeUInt32LE(attributes, 38);
        ch.writeUInt32LE(offset, 42);
        central.push(ch, Buffer.from(cnb), Buffer.from(cex));

        offset += 30 + lnb.length + lex.length + data.length;
    }
    const cd = Buffer.concat(central);
    const comment = options.comment ?? new Uint8Array();
    const zip64 = options.zip64 === true;
    const records: Buffer[] = [...local, cd];
    if (zip64) {
        const eocd64 = Buffer.alloc(56);
        eocd64.writeUInt32LE(0x06064b50, 0);
        eocd64.writeBigUInt64LE(44n, 4);
        eocd64.writeUInt16LE(20, 12);
        eocd64.writeUInt16LE(45, 14);
        eocd64.writeBigUInt64LE(BigInt(entries.length), 24);
        eocd64.writeBigUInt64LE(BigInt(entries.length), 32);
        eocd64.writeBigUInt64LE(BigInt(cd.length), 40);
        eocd64.writeBigUInt64LE(BigInt(offset), 48);
        const locator = Buffer.alloc(20);
        locator.writeUInt32LE(0x07064b50, 0);
        locator.writeBigUInt64LE(BigInt(offset + cd.length), 8);
        locator.writeUInt32LE(1, 16);
        records.push(eocd64, locator);
    }
    const eocd = Buffer.alloc(22);
    eocd.writeUInt32LE(0x06054b50, 0);
    eocd.writeUInt16LE(zip64 ? 0xffff : entries.length, 8);
    eocd.writeUInt16LE(zip64 ? 0xffff : entries.length, 10);
    eocd.writeUInt32LE(zip64 ? 0xffffffff : cd.length, 12);
    eocd.writeUInt32LE(zip64 ? 0xffffffff : offset, 16);
    eocd.writeUInt16LE(comment.length, 20);
    records.push(eocd, Buffer.from(comment));
    if (options.trailing) records.push(Buffer.from(options.trailing));
    const out = Buffer.concat(records);
    options.patch?.(out, {
        cdOffset: offset,
        cdSize: cd.length,
        eocdOffset: out.length - (options.trailing?.length ?? 0) - comment.length - 22,
        count: entries.length,
    });
    return out;
};

/** Minimal DOCX part set, identical to tests/support/minimal-docx.ts. */
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";

export const MINIMAL_PARTS: Record<string, string> = {
    "[Content_Types].xml":
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">` +
        `<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>` +
        `<Default Extension="xml" ContentType="application/xml"/>` +
        `<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>` +
        `<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>` +
        `</Types>`,
    "_rels/.rels":
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">` +
        `<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>` +
        `</Relationships>`,
    "word/_rels/document.xml.rels":
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">` +
        `<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>` +
        `</Relationships>`,
    "word/document.xml":
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<w:document xmlns:w="${W}" xmlns:w14="${W14}" xmlns:mc="${MC}" mc:Ignorable="w14">` +
        `<w:body><w:p w14:paraId="00000001" w14:textId="00000001"><w:r><w:t>Hello</w:t></w:r></w:p>` +
        `<w:sectPr><w:pgSz w:w="12240" w:h="15840"/>` +
        `<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/>` +
        `</w:sectPr></w:body></w:document>`,
    "word/styles.xml":
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<w:styles xmlns:w="${W}">` +
        `<w:docDefaults><w:rPrDefault><w:rPr/></w:rPrDefault><w:pPrDefault><w:pPr/></w:pPrDefault></w:docDefaults>` +
        `<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/></w:style>` +
        `<w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/></w:style>` +
        `<w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/></w:style>` +
        `<w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/></w:style>` +
        `</w:styles>`,
};

/** SpecEntry[] for the minimal DOCX, with optional per-name overrides. */
export const docxEntries = (overrides: (e: SpecEntry) => SpecEntry[] = (e) => [e]): SpecEntry[] =>
    Object.entries(MINIMAL_PARTS).flatMap(([name, content]) => overrides({ name, content }));
```

The specimen definitions observed in session 4d (`ry-<name>` is review Y's `<name>`):

<!-- prettier-ignore -->
```ts
// --- local name differs from central name (JSZip uses the LOCAL name) ---
specimens["local-dotdot"] = buildSpecZip([...docxEntries(), { name: "word/extra.xml", localName: "../evil.xml", content: "<x/>" }]);
specimens["central-dotdot-local-clean"] = buildSpecZip([...docxEntries(), { name: "evil/../x.xml", localName: "x.xml", content: "<x/>" }]);
// central duplicates with distinct local names: which entry's bytes are read?
specimens["dup-central-distinct-local"] = buildSpecZip([
    ...docxEntries((e) =>
        e.name === "word/document.xml"
            ? [
                  { ...e, localName: "AAAA-first.xml" },
                  { name: "word/document.xml", localName: "BBBB-second.xml", content: "<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:body><w:p/></w:body></w:document>" },
              ]
            : [e],
    ),
]);

// --- Info-ZIP unicode path extra field (0x7075) ---
const upath = (nameBytes: Uint8Array, unicode: string): Uint8Array => {
    const u = new TextEncoder().encode(unicode);
    const field = Buffer.alloc(4 + 1 + 4 + u.length);
    field.writeUInt16LE(0x7075, 0);
    field.writeUInt16LE(1 + 4 + u.length, 2);
    field.writeUInt8(1, 4);
    field.writeUInt32LE(crc32(nameBytes), 5);
    field.set(u, 9);
    return field;
};
{
    const nb = new TextEncoder().encode("a/../x.xml");
    specimens["upath-hides-dotdot"] = buildSpecZip([
        ...docxEntries(),
        { name: "a/../x.xml", nameBytes: nb, localExtra: upath(nb, "x.xml"), centralExtra: upath(nb, "x.xml"), content: "<x/>" },
    ]);
    const nb2 = new TextEncoder().encode("x.xml");
    specimens["upath-injects-dotdot"] = buildSpecZip([
        ...docxEntries(),
        { name: "x.xml", nameBytes: nb2, localExtra: upath(nb2, "../evil.xml"), centralExtra: upath(nb2, "../evil.xml"), content: "<x/>" },
    ]);
}
// CP437 é (0x82) without UTF-8 flag
specimens["cp437-name"] = buildSpecZip([
    ...docxEntries(),
    { name: "x", nameBytes: Uint8Array.from([0x63, 0x61, 0x66, 0x82, 0x2e, 0x78, 0x6d, 0x6c]), content: "<x/>" },
]);

```

Session 6 builds each specimen from the same `buildSpecZip` and `docxEntries()`, adding one entry `{ nameBytes, utf8, content: "<x/>" }`:

<!-- prettier-ignore -->
```ts
const utf8 = (s: string) => new TextEncoder().encode(s);
const cases: Record<string, { nameBytes: Uint8Array; utf8?: boolean }> = {
    // session 6a
    "s6-cp437-byte-noflag": { nameBytes: Uint8Array.from([0x63, 0x61, 0x66, 0x82, 0x2e, 0x78, 0x6d, 0x6c]) },
    "s6-utf8-bytes-flag": { nameBytes: utf8("café.xml"), utf8: true },
    "s6-utf8-bytes-noflag": { nameBytes: utf8("café.xml") },
    "s6-pct-encoded-ascii": { nameBytes: utf8("caf%C3%A9.xml") },
    "s6-ascii-control": { nameBytes: utf8("cafe.xml") },
    // session 6b
    "s6-pct-ascii-space-root": { nameBytes: utf8("caf%20.xml") },
    "s6-pct-latin1-e9": { nameBytes: utf8("caf%E9.xml") },
    "s6-utf8-flag-in-word": { nameBytes: utf8("word/café.xml"), utf8: true },
    "s6-ascii-control-in-word": { nameBytes: utf8("word/cafe.xml") },
};
for (const [name, c] of Object.entries(cases)) {
    const bytes = buildSpecZip([...docxEntries(), { name: "x", nameBytes: c.nameBytes, utf8: c.utf8, content: "<x/>" }]);
    writeFileSync(path.join(DIR, `${name}.docx`), bytes);
}
```

Each run is `zsh run-chunk.sh <run>`, then `python3 wordpdf_outcomes.py <run>` (the session 3 parser above). A single-specimen run is a copy made by `python3 mkchunk.py <run> <batch>:<specimen>`:

<!-- prettier-ignore -->
```sh
#!/bin/zsh
# One foreground real-Word run of a specimen chunk through neurotic_docx_bench's
# word_pdf.py, in its default batch mode (Word brought forward to answer alerts).
# Usage: zsh run-chunk.sh <chunk-dir-name>   (holds src/ and specimens.jsonl)
#
# A leftover word_watchdog.sh SIGKILLs Word once the log it watches idles 60 s,
# which would end this run mid-item. Pause every watchdog for this run only and
# resume them on exit.
set -u
run=/Users/arthrod/temp/T/wfv-scratch/word-probes/$1
[[ -d $run/src ]] || { echo "no $run/src"; exit 2; }
paused=()
for p in $(pgrep -f word_watchdog.sh); do kill -STOP $p && paused+=($p); done
trap 'for p in $paused; do kill -CONT $p; done; echo "resumed watchdogs: ${paused[*]:-none}"' EXIT
echo "paused watchdogs: ${paused[*]:-none}; start $(date -u +%FT%TZ)"
cd /Users/arthrod/temp/T/neurotic_docx_bench
uv run --script scripts/word_pdf.py --src $run/src --out $run/pdf --log $run/word_pdf.log --label wfv --no-check-preset --lock-wait 300
echo "word_pdf exit=$? end $(date -u +%FT%TZ)"
```

<!-- prettier-ignore -->
```python
"""mkchunk.py <new-chunk> <src-chunk>:<name> [...] — copy specimens (file + specimens.jsonl row) into a new chunk dir."""
import json, shutil, sys
from pathlib import Path
new = Path(sys.argv[1]); (new / "src").mkdir(parents=True, exist_ok=True)
with open(new / "specimens.jsonl", "w") as out:
    for arg in sys.argv[2:]:
        src, name = arg.split(":", 1)
        rows = [json.loads(l) for l in (Path(src) / "specimens.jsonl").read_text().splitlines() if l.strip()]
        row = next(r for r in rows if r["name"] == name)
        shutil.copy2(Path(src) / "src" / row["file"], new / "src" / row["file"])
        out.write(json.dumps(row) + "\n")
print(new, len(sys.argv) - 2)
```

Session 7's builder is a standalone script, run as a copy from the stack worktree root with `BUILD_DIR=<run>/src pnpm exec tsx s7builder.tmp.mts` (the `s7c` rows and the `ONLY` filter were added after `s7` ran; `s7b` and `s7c` were built with `ONLY=<specimens>`, and the builders of the `s7` rows are unchanged):

```ts
// Session 7 (2026-10-24): #414 Override PartName shapes no session has shown Word yet — a segment
// ending with '.', and characters outside the RFC 3986 pchar set — plus grammar-valid controls.
// Each is an application/xml Override of a missing part, as in sessions 4 and 5.
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src pnpm exec tsx s7builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const override = (partName: string) =>
    buildDocx({
        ...P,
        "[Content_Types].xml": CT.replace("</Types>", `<Override PartName="${partName}" ContentType="application/xml"/></Types>`),
    });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s7-control-minimal", "control", () => buildDocx(P)],
    ["414-xml-plain-missing-control-s7", "#414", () => override("/word/nothere.xml")],
    ["414-xml-trailing-dot-missing", "#414", () => override("/word/nothere.xml.")],
    ["414-xml-folder-dot-missing", "#414", () => override("/word./nothere.xml")],
    ["414-xml-space-missing", "#414", () => override("/word/no there.xml")],
    ["414-xml-bracket-missing", "#414", () => override("/word/no[there].xml")],
    ["414-xml-nonascii-missing", "#414", () => override("/word/café.xml")],
    ["414-xml-pct20-missing-control", "#414", () => override("/word/no%20there.xml")],
    ["414-xml-pctC3A9-missing", "#414", () => override("/word/caf%C3%A9.xml")],
    ["s7-control-minimal-end", "control", () => buildDocx(P)],
    // s7c: the folder-dot shape opened clean in s7; confirm it alone and in a deeper folder.
    ["414-xml-folder-dot-deep-missing", "#414", () => override("/word/sub./nothere.xml")],
    ["414-xml-folder-dot-root-missing", "#414", () => override("/x./nothere.xml")],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return { valid: r.valid, errors: r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`) };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Sessions 8–13 use two more standalone builders, run the same way. Each chunk was built with `ONLY=<its specimens>`; rows were only appended to the builders after earlier chunks ran, so the builders of the observed rows are unchanged. Session 8's builder (`s8a`, `s8b`):

```ts
// Session 8 (2026-10-24): open questions behind #432 (parts typed by the generic Default), #443 (a non-ASCII
// stored name that a relationship targets), #451 (other escapes in an Override PartName) and #437 (malformed
// parts that a known relationship names but the document never uses).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s8builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
const MAIN_OVERRIDE = `<Override PartName="/word/document.xml" ContentType="${WML}.document.main+xml"/>`;
const STYLES_OVERRIDE = `<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml"/>`;
const truncated = (xml: string) => xml.slice(0, 60);

const ct = (extra: string, drop: readonly string[] = []) =>
    drop
        .reduce((acc, d) => {
            if (!acc.includes(d)) throw new Error(`no ${d}`);
            return acc.replace(d, "");
        }, CT)
        .replace("</Types>", `${extra}</Types>`);
const rels = (extra: string, base = DOC_RELS) => base.replace("</Relationships>", `${extra}</Relationships>`);

/** A part named by a document relationship, with or without its own Override. */
const withPart = (name: string, type: string, contentType: string | undefined, xml: string) =>
    buildDocx({
        ...P,
        [`word/${name}`]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${type}" Target="${name}"/>`),
        "[Content_Types].xml": ct(contentType ? `<Override PartName="/word/${name}" ContentType="${contentType}"/>` : ""),
    });

const override = (partName: string) =>
    buildDocx({ ...P, "[Content_Types].xml": ct(`<Override PartName="${partName}" ContentType="application/xml"/>`) });

/** The styles part stored under `stored`, typed by a `sty` Default, its relationship targeting `target`. */
const stylesAt = (stored: string, target: string) => {
    const { "word/styles.xml": styles, ...rest } = P;
    return buildDocx({
        ...rest,
        [stored]: styles,
        "word/_rels/document.xml.rels": DOC_RELS.replace(`Target="styles.xml"`, `Target="${target}"`),
        "[Content_Types].xml": ct(`<Default Extension="sty" ContentType="${WML}.styles+xml"/>`, [STYLES_OVERRIDE]),
    });
};

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s8-control-minimal", "control", () => buildDocx(P)],
    // #432: each part typed only by <Default Extension="xml" ContentType="application/xml"/>, against its control.
    [
        "432-settings-override-control",
        "#432",
        () => withPart("settings.xml", "settings", `${WML}.settings+xml`, `<w:settings xmlns:w="${W}"/>`),
    ],
    ["432-settings-generic-default", "#432", () => withPart("settings.xml", "settings", undefined, `<w:settings xmlns:w="${W}"/>`)],
    [
        "432-fonttable-override-control",
        "#432",
        () => withPart("fontTable.xml", "fontTable", `${WML}.fontTable+xml`, `<w:fonts xmlns:w="${W}"/>`),
    ],
    ["432-fonttable-generic-default", "#432", () => withPart("fontTable.xml", "fontTable", undefined, `<w:fonts xmlns:w="${W}"/>`)],
    [
        "432-websettings-override-control",
        "#432",
        () => withPart("webSettings.xml", "webSettings", `${WML}.webSettings+xml`, `<w:webSettings xmlns:w="${W}"/>`),
    ],
    [
        "432-websettings-generic-default",
        "#432",
        () => withPart("webSettings.xml", "webSettings", undefined, `<w:webSettings xmlns:w="${W}"/>`),
    ],
    ["432-main-generic-default", "#432", () => buildDocx({ ...P, "[Content_Types].xml": ct("", [MAIN_OVERRIDE]) })],
    ["432-styles-generic-default-s8", "#432", () => buildDocx({ ...P, "[Content_Types].xml": ct("", [STYLES_OVERRIDE]) })],
    // #443: a non-ASCII stored name that the styles relationship targets, typed by an extension Default (no PartName).
    ["443-styles-ascii-sty-control", "#443", () => stylesAt("word/styles.sty", "styles.sty")],
    ["443-styles-nonascii-sty-referenced", "#443", () => stylesAt("word/stylés.sty", "stylés.sty")],
    ["443-styles-nonascii-sty-referenced-escaped-target", "#443", () => stylesAt("word/stylés.sty", "styl%C3%A9s.sty")],
    ["s8-control-minimal-mid", "control", () => buildDocx(P)],
    // #451: other escapes in an Override PartName of a missing part.
    ["451-pctE9-missing", "#451", () => override("/word/caf%E9.xml")],
    ["451-pct21-missing", "#451", () => override("/word/a%21b.xml")],
    ["451-pct7F-missing", "#451", () => override("/word/a%7Fb.xml")],
    // #437: a malformed part that a known relationship names, but nothing in the document uses.
    [
        "437-customxml-rel-malformed",
        "#437",
        () =>
            buildDocx({
                ...P,
                "customXml/item1.xml": truncated(P["word/styles.xml"]),
                "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/customXml" Target="../customXml/item1.xml"/>`),
            }),
    ],
    [
        "437-customxml-rel-wellformed-control",
        "#437",
        () =>
            buildDocx({
                ...P,
                "customXml/item1.xml": `<root/>`,
                "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/customXml" Target="../customXml/item1.xml"/>`),
            }),
    ],
    [
        "437-footer-rel-unused-malformed",
        "#437",
        () =>
            withPart(
                "footer1.xml",
                "footer",
                `${WML}.footer+xml`,
                truncated(`<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>footer text here</w:t></w:r></w:p></w:ftr>`),
            ),
    ],
    [
        "437-footer-rel-unused-wellformed-control",
        "#437",
        () => withPart("footer1.xml", "footer", `${WML}.footer+xml`, `<w:ftr xmlns:w="${W}"><w:p/></w:ftr>`),
    ],
    [
        "437-comments-rel-malformed",
        "#437",
        () =>
            withPart(
                "comments.xml",
                "comments",
                `${WML}.comments+xml`,
                truncated(`<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p/></w:comment></w:comments>`),
            ),
    ],
    [
        "437-comments-rel-wellformed-control",
        "#437",
        () => withPart("comments.xml", "comments", `${WML}.comments+xml`, `<w:comments xmlns:w="${W}"/>`),
    ],
    ["s8-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

The builder of sessions 9–13 (`s9a`, `s9b`, `s10`–`s13`):

```ts
// Sessions 9 to 13 (2026-10-24): boundaries behind #437 (which malformed parts Word parses: related-and-used versus
// related-only) and #451/#408 (which percent-escapes Word refuses, in an Override PartName and in a stored name).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s9builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));

const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const withR = (doc: string) => doc.replace(`xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`);

/** A part named by a document relationship with its Override; `doc` replaces the main part when given. */
const withPart = (name: string, type: string, contentType: string, xml: string, doc?: string) =>
    buildDocx({
        ...P,
        ...(doc ? { "word/document.xml": doc } : {}),
        [`word/${name}`]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${type}" Target="${name}"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/${name}" ContentType="${contentType}"/>`),
    });

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const footerDoc = withR(DOC).replace("<w:sectPr>", `<w:sectPr><w:footerReference w:type="default" r:id="rIdX"/>`);
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:comment></w:comments>`;
const commentDoc = DOC.replace(
    `<w:r><w:t>Hello</w:t></w:r>`,
    `<w:commentRangeStart w:id="0"/><w:r><w:t>Hello</w:t></w:r><w:commentRangeEnd w:id="0"/><w:r><w:commentReference w:id="0"/></w:r>`,
);
const FOOTNOTES =
    `<w:footnotes xmlns:w="${W}"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote></w:footnotes>`;

const override = (partName: string) =>
    buildDocx({ ...P, "[Content_Types].xml": ct(`<Override PartName="${partName}" ContentType="application/xml"/>`) });
const storedExtra = (name: string) => buildDocx({ ...P, [name]: "<x/>" });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s9-control-minimal", "control", () => buildDocx(P)],
    // #437: related and used, against related only.
    ["437-footer-referenced-malformed", "#437", () => withPart("footer1.xml", "footer", `${WML}.footer+xml`, unclosed(FOOTER), footerDoc)],
    ["437-footer-referenced-wellformed-control", "#437", () => withPart("footer1.xml", "footer", `${WML}.footer+xml`, FOOTER, footerDoc)],
    ["437-footer-related-unused-unclosed", "#437", () => withPart("footer1.xml", "footer", `${WML}.footer+xml`, unclosed(FOOTER))],
    [
        "437-comments-referenced-malformed",
        "#437",
        () => withPart("comments.xml", "comments", `${WML}.comments+xml`, unclosed(COMMENTS), commentDoc),
    ],
    [
        "437-comments-referenced-wellformed-control",
        "#437",
        () => withPart("comments.xml", "comments", `${WML}.comments+xml`, COMMENTS, commentDoc),
    ],
    ["437-comments-related-unused-unclosed", "#437", () => withPart("comments.xml", "comments", `${WML}.comments+xml`, unclosed(COMMENTS))],
    [
        "437-settings-malformed",
        "#437",
        () =>
            withPart(
                "settings.xml",
                "settings",
                `${WML}.settings+xml`,
                unclosed(`<w:settings xmlns:w="${W}"><w:zoom w:percent="100"/></w:settings>`),
            ),
    ],
    [
        "437-fonttable-malformed",
        "#437",
        () =>
            withPart(
                "fontTable.xml",
                "fontTable",
                `${WML}.fontTable+xml`,
                unclosed(`<w:fonts xmlns:w="${W}"><w:font w:name="Calibri"/></w:fonts>`),
            ),
    ],
    [
        "437-websettings-malformed",
        "#437",
        () =>
            withPart(
                "webSettings.xml",
                "webSettings",
                `${WML}.webSettings+xml`,
                unclosed(`<w:webSettings xmlns:w="${W}"><w:optimizeForBrowser/></w:webSettings>`),
            ),
    ],
    [
        "437-numbering-related-unused-malformed",
        "#437",
        () =>
            withPart(
                "numbering.xml",
                "numbering",
                `${WML}.numbering+xml`,
                unclosed(`<w:numbering xmlns:w="${W}"><w:num w:numId="1"/></w:numbering>`),
            ),
    ],
    [
        "437-footnotes-related-unused-malformed",
        "#437",
        () => withPart("footnotes.xml", "footnotes", `${WML}.footnotes+xml`, unclosed(FOOTNOTES)),
    ],
    [
        "437-footnotes-related-unused-wellformed-control",
        "#437",
        () => withPart("footnotes.xml", "footnotes", `${WML}.footnotes+xml`, FOOTNOTES),
    ],
    ["s9-control-minimal-mid", "control", () => buildDocx(P)],
    // #451: escapes of pchar characters (sub-delims, ':' and '@') and of characters that need escaping, in a PartName.
    ["451-pct3A-missing", "#451", () => override("/word/a%3Ab.xml")],
    ["451-pct40-missing", "#451", () => override("/word/a%40b.xml")],
    ["451-pct24-missing", "#451", () => override("/word/a%24b.xml")],
    ["451-pct3D-missing", "#451", () => override("/word/a%3Db.xml")],
    ["451-pct2C-missing", "#451", () => override("/word/a%2Cb.xml")],
    ["451-pct25-missing", "#451", () => override("/word/a%25b.xml")],
    ["451-pct22-missing", "#451", () => override("/word/a%22b.xml")],
    ["451-pct5B-missing", "#451", () => override("/word/a%5Bb.xml")],
    ["451-pct7B-missing", "#451", () => override("/word/a%7Bb.xml")],
    ["451-pct3C-missing", "#451", () => override("/word/a%3Cb.xml")],
    // #408: the same question for an unreferenced stored name.
    ["408-stored-pct21-unreferenced", "#408", () => storedExtra("word/a%21b.xml")],
    ["408-stored-pct3A-unreferenced", "#408", () => storedExtra("word/a%3Ab.xml")],
    ["408-stored-pct5B-unreferenced", "#408", () => storedExtra("word/a%5Bb.xml")],
    ["408-stored-pct7F-unreferenced", "#408", () => storedExtra("word/a%7Fb.xml")],
    ["s9-control-minimal-end", "control", () => buildDocx(P)],
    // Session 10: a literal '!', and the remaining sub-delim escapes.
    ["s10-control-minimal", "control", () => buildDocx(P)],
    ["451-literal-bang-missing", "#451", () => override("/word/a!b.xml")],
    ["408-stored-literal-bang-unreferenced", "#408", () => storedExtra("word/a!b.xml")],
    ["451-pct26-missing", "#451", () => override("/word/a%26b.xml")],
    ["451-pct27-missing", "#451", () => override("/word/a%27b.xml")],
    ["451-pct28-missing", "#451", () => override("/word/a%28b.xml")],
    ["451-pct29-missing", "#451", () => override("/word/a%29b.xml")],
    ["451-pct2A-missing", "#451", () => override("/word/a%2Ab.xml")],
    ["451-pct2B-missing", "#451", () => override("/word/a%2Bb.xml")],
    ["451-pct3B-missing", "#451", () => override("/word/a%3Bb.xml")],
    ["451-pct21-lower-missing-s10", "#451", () => override("/word/a%21b.xml")],
    ["s10-control-minimal-end", "control", () => buildDocx(P)],
    // Session 11: the rest of RFC 3986 unreserved, lower-case hex, and escapes above 0x7F, in a PartName and stored.
    ["s11-control-minimal", "control", () => buildDocx(P)],
    ["451-pct7E-missing", "#451", () => override("/word/a%7Eb.xml")],
    ["451-pct2D-missing", "#451", () => override("/word/a%2Db.xml")],
    ["451-pct5F-missing", "#451", () => override("/word/a%5Fb.xml")],
    ["451-pct2E-missing", "#451", () => override("/word/a%2Eb.xml")],
    ["451-pct41-missing", "#451", () => override("/word/a%41b.xml")],
    ["451-pct39-missing", "#451", () => override("/word/a%39b.xml")],
    ["451-pct2a-lower-missing", "#451", () => override("/word/a%2ab.xml")],
    ["451-pct01-missing", "#451", () => override("/word/a%01b.xml")],
    ["451-pct80-missing", "#451", () => override("/word/a%80b.xml")],
    ["451-pctFF-missing", "#451", () => override("/word/a%FFb.xml")],
    ["408-stored-pct27-unreferenced", "#408", () => storedExtra("word/a%27b.xml")],
    ["408-stored-pct2A-unreferenced", "#408", () => storedExtra("word/a%2Ab.xml")],
    ["408-stored-pct7E-unreferenced", "#408", () => storedExtra("word/a%7Eb.xml")],
    ["408-stored-pct26-unreferenced", "#408", () => storedExtra("word/a%26b.xml")],
    ["s11-control-minimal-end", "control", () => buildDocx(P)],
    // Session 12: dot-only folder segments (review AB S1), and the remaining stored-name escapes.
    ["s12-control-minimal", "control", () => buildDocx(P)],
    ["450-dots3-folder-missing", "#450", () => override("/word/.../x.xml")],
    ["450-dots4-folder-missing", "#450", () => override("/word/..../x.xml")],
    ["450-dots3-first-folder-missing", "#450", () => override("/.../x.xml")],
    ["450-word-dot-folder-control-s12", "#450", () => override("/word./x.xml")],
    ["408-stored-pct28-unreferenced", "#408", () => storedExtra("word/a%28b.xml")],
    ["408-stored-pct29-unreferenced", "#408", () => storedExtra("word/a%29b.xml")],
    ["408-stored-pctC3A9-unreferenced", "#408", () => storedExtra("word/caf%C3%A9.xml")],
    ["408-stored-pct80-unreferenced", "#408", () => storedExtra("word/a%80b.xml")],
    ["s12-control-minimal-end", "control", () => buildDocx(P)],
    // Session 13: an Override without a PartName, with an empty one, and with "/" alone (review AA S2).
    ["s13-control-minimal", "control", () => buildDocx(P)],
    ["414-override-no-partname", "#414", () => buildDocx({ ...P, "[Content_Types].xml": ct(`<Override ContentType="application/xml"/>`) })],
    ["414-override-empty-partname", "#414", () => override("")],
    ["414-override-slash-only", "#414", () => override("/")],
    ["s13-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 14's builder (`s14a`, `s14b`) is another standalone script, run the same way; each chunk was built with `ONLY=<its specimens>`:

```ts
// Session 14 (2026-10-24): Markup Compatibility in [Content_Types].xml (#459) and prefixed packages (#464).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s14builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { buildRawZip } from "./tests/support/raw-zip";
import { validate } from "./src/scripts/office/validate";

const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const TYPES_OPEN = CT.match(/<Types [^>]*>/)![0];

/** The content-types stream with extra namespace declarations/attributes on the root and extra children. */
const ct = (rootExtra: string, children: string) =>
    CT.replace(TYPES_OPEN, TYPES_OPEN.replace(/>$/, ` ${rootExtra}>`)).replace("</Types>", `${children}</Types>`);
const withCt = (rootExtra: string, children: string) => buildDocx({ ...P, "[Content_Types].xml": ct(rootExtra, children) });
const MC_DECL = `xmlns:mc="${MC}" xmlns:x="urn:x:unknown"`;
// An Override Word refuses on its own (OPC [M1.8], session 11: repair-warning) and one it accepts (session 7: clean).
const BAD = `<Override PartName="/word/a%41b.xml" ContentType="application/xml"/>`;
const GOOD = `<Override PartName="/word/fallback.xml" ContentType="application/xml"/>`;
const alternate = (choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="x">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A ZIP whose offsets are absolute in a buffer with `prefix` bytes in front, as a self-extractor writes them. */
const absoluteAfter = (zip: Uint8Array, prefix: number): Buffer => {
    const buf = Buffer.from(zip);
    const eocd = buf.lastIndexOf(Buffer.from([0x50, 0x4b, 0x05, 0x06]));
    const count = buf.readUInt16LE(eocd + 10);
    let offset = buf.readUInt32LE(eocd + 16);
    buf.writeUInt32LE(offset + prefix, eocd + 16);
    for (let i = 0; i < count; i += 1) {
        if (buf.readUInt32LE(offset) !== 0x02014b50) throw new Error("bad central header");
        buf.writeUInt32LE(buf.readUInt32LE(offset + 42) + prefix, offset + 42);
        offset += 46 + buf.readUInt16LE(offset + 28) + buf.readUInt16LE(offset + 30) + buf.readUInt16LE(offset + 32);
    }
    return buf;
};
const JUNK = Buffer.alloc(4096, 0x20);
const PREFIX_ZIP = buildRawZip([
    { name: "pad.bin", content: Buffer.alloc(600) },
    { name: "ok.xml", content: "<x/>" },
]);

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s14a-control-minimal", "control", () => buildDocx(P)],
    ["459-mc-namespace-declared-only", "#459", () => withCt(MC_DECL, "")],
    ["459-mc-ignorable-only", "#459", () => withCt(`${MC_DECL} mc:Ignorable="x"`, "")],
    ["459-mc-ignorable-ignored-element", "#459", () => withCt(`${MC_DECL} mc:Ignorable="x"`, `<x:Foo/>`)],
    ["459-mc-choice-bad-fallback-good", "#459", () => withCt(MC_DECL, alternate(BAD, GOOD))],
    ["459-mc-choice-good-fallback-bad", "#459", () => withCt(MC_DECL, alternate(GOOD, BAD))],
    ["s14a-control-minimal-end", "control", () => buildDocx(P)],
    ["s14b-control-minimal", "control", () => buildDocx(P)],
    ["464-prefix-zip-docx", "#464", async () => Buffer.concat([PREFIX_ZIP, await buildDocx(P)])],
    ["464-prefix-junk-docx-relative", "#464", async () => Buffer.concat([JUNK, await buildDocx(P)])],
    ["464-prefix-junk-docx-absolute", "#464", async () => Buffer.concat([JUNK, absoluteAfter(await buildDocx(P), JUNK.length)])],
    ["s14b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 15's builder (`s15a`–`s15e`) is another standalone script, run the same way; each chunk was built with `ONLY=<its specimens>`:

```ts
// Session 15 (2026-10-24): review AM's suspected false negatives and positives of layers 78-79 (#437, #432):
// which relationship-reached parts Word parses beyond sessions 7-9, and which generic content types it refuses.
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s15builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));

const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const withR = (doc: string) => doc.replace(`xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`);

/** A part named by a document relationship with its Override; `doc` replaces the main part when given. */
const withPart = (name: string, type: string, contentType: string, xml: string, doc?: string) =>
    buildDocx({
        ...P,
        ...(doc ? { "word/document.xml": doc } : {}),
        [`word/${name}`]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${type}" Target="${name}"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/${name}" ContentType="${contentType}"/>`),
    });

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const footerDoc = withR(DOC).replace("<w:sectPr>", `<w:sectPr><w:footerReference w:type="default" r:id="rIdX"/>`);
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:comment></w:comments>`;
const commentDoc = DOC.replace(
    `<w:r><w:t>Hello</w:t></w:r>`,
    `<w:commentRangeStart w:id="0"/><w:r><w:t>Hello</w:t></w:r><w:commentRangeEnd w:id="0"/><w:r><w:commentReference w:id="0"/></w:r>`,
);
const FOOTNOTES =
    `<w:footnotes xmlns:w="${W}"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote></w:footnotes>`;

const override = (partName: string) =>
    buildDocx({ ...P, "[Content_Types].xml": ct(`<Override PartName="${partName}" ContentType="application/xml"/>`) });
const storedExtra = (name: string) => buildDocx({ ...P, [name]: "<x/>" });

const PKG_RELS = P["_rels/.rels"];
const pkgRels = (extra: string) => PKG_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const MAIN = `${WML}.document.main+xml`;
const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const ENDNOTES =
    `<w:endnotes xmlns:w="${W}"><w:endnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:endnote></w:endnotes>`;
const rangeOnlyDoc = DOC.replace(
    `<w:r><w:t>Hello</w:t></w:r>`,
    `<w:commentRangeStart w:id="0"/><w:r><w:t>Hello</w:t></w:r><w:commentRangeEnd w:id="0"/>`,
);
const headerDoc = withR(DOC).replace("<w:sectPr>", `<w:sectPr><w:headerReference w:type="default" r:id="rIdX"/>`);
const endnoteDoc = DOC.replace(`<w:r><w:t>Hello</w:t></w:r>`, `<w:r><w:t>Hello</w:t></w:r><w:r><w:endnoteReference w:id="1"/></w:r>`);

/** A part outside word/, named by a document relationship with its Override. */
const outsidePart = (stored: string, type: string, contentType: string, xml: string, doc: string) =>
    buildDocx({
        ...P,
        "word/document.xml": doc,
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${type}" Target="../${stored}"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/${stored}" ContentType="${contentType}"/>`),
    });

/** A second officeDocument relationship to alt/document.xml, with its Override; `extra` adds parts. */
const secondMain = (altDoc: string, extra: Record<string, string> = {}) =>
    buildDocx({
        ...P,
        "_rels/.rels": pkgRels(`<Relationship Id="rId9" Type="${REL}/officeDocument" Target="alt/document.xml"/>`),
        "alt/document.xml": altDoc,
        ...extra,
        "[Content_Types].xml": ct(`<Override PartName="/alt/document.xml" ContentType="${MAIN}"/>`),
    });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s15a — F4: the main document's own relationships part, malformed; F7: a comment range with no commentReference.
    ["s15a-control-minimal", "control", () => buildDocx(P)],
    ["am-f4-docrels-unclosed", "#437 AM-F4", () => buildDocx({ ...P, "word/_rels/document.xml.rels": unclosed(DOC_RELS) })],
    ["am-f4-docrels-zero-byte", "#437 AM-F4", () => buildDocx({ ...P, "word/_rels/document.xml.rels": "" })],
    [
        "am-f7-comments-rangeonly-malformed",
        "#437 AM-F7",
        () => withPart("comments.xml", "comments", `${WML}.comments+xml`, unclosed(COMMENTS), rangeOnlyDoc),
    ],
    [
        "am-f7-comments-rangeonly-wellformed-control",
        "#437 AM-F7",
        () => withPart("comments.xml", "comments", `${WML}.comments+xml`, COMMENTS, rangeOnlyDoc),
    ],
    ["s15a-control-minimal-end", "control", () => buildDocx(P)],
    // s15b — F6: a second officeDocument relationship; F9: the main document typed generically another way.
    ["s15b-control-minimal", "control", () => buildDocx(P)],
    ["am-f6-second-officedoc-malformed", "#437 AM-F6", () => secondMain(unclosed(DOC))],
    ["am-f6-second-officedoc-wellformed-control", "#437 AM-F6", () => secondMain(DOC)],
    [
        "am-f6-second-officedoc-generic-styles",
        "#432 AM-F6",
        () => secondMain(DOC, { "alt/_rels/document.xml.rels": DOC_RELS, "alt/styles.xml": P["word/styles.xml"] }),
    ],
    [
        "am-f9-main-default-textxml",
        "#432 AM-F9",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    `<Default Extension="xml" ContentType="application/xml"/>`,
                    `<Default Extension="xml" ContentType="text/xml"/>`,
                ).replace(`<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`, ""),
            }),
    ],
    [
        "am-f9-main-override-appxml",
        "#432 AM-F9",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    `<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`,
                    `<Override PartName="/word/document.xml" ContentType="application/xml"/>`,
                ),
            }),
    ],
    ["s15b-control-minimal-end", "control", () => buildDocx(P)],
    // s15c — F8: used header and endnotes stored outside word/; F5: styles named by a relationship Word may not follow.
    ["s15c-control-minimal", "control", () => buildDocx(P)],
    [
        "am-f8-header-outside-word-malformed",
        "#437 AM-F8",
        () => outsidePart("hdr/header1.xml", "header", `${WML}.header+xml`, unclosed(HEADER), headerDoc),
    ],
    [
        "am-f8-header-outside-word-wellformed-control",
        "#437 AM-F8",
        () => outsidePart("hdr/header1.xml", "header", `${WML}.header+xml`, HEADER, headerDoc),
    ],
    [
        "am-f8-endnotes-outside-word-malformed",
        "#437 AM-F8",
        () => outsidePart("en/endnotes.xml", "endnotes", `${WML}.endnotes+xml`, unclosed(ENDNOTES), endnoteDoc),
    ],
    [
        "am-f5-styles-ms-namespace-malformed",
        "#437 AM-F5",
        () =>
            buildDocx({
                ...P,
                "word/_rels/document.xml.rels": DOC_RELS.replace(
                    `${REL}/styles`,
                    "http://schemas.microsoft.com/office/2007/relationships/styles",
                ),
                "word/styles.xml": unclosed(P["word/styles.xml"]),
            }),
    ],
    [
        "am-f5-styles-package-rels-malformed",
        "#437 AM-F5",
        () =>
            buildDocx({
                ...P,
                "_rels/.rels": pkgRels(`<Relationship Id="rId9" Type="${REL}/styles" Target="word/styles2.xml"/>`),
                "word/styles2.xml": unclosed(P["word/styles.xml"]),
                "[Content_Types].xml": ct(`<Override PartName="/word/styles2.xml" ContentType="${WML}.styles+xml"/>`),
            }),
    ],
    ["s15c-control-minimal-end", "control", () => buildDocx(P)],
    // s15d — F6: which part of a second officeDocument relationship Word refuses; F8: theme and glossary outside word/.
    ["s15d-control-minimal", "control", () => buildDocx(P)],
    [
        "am-f6-second-officedoc-no-override",
        "#437 AM-F6",
        () =>
            buildDocx({
                ...P,
                "_rels/.rels": pkgRels(`<Relationship Id="rId9" Type="${REL}/officeDocument" Target="alt/document.xml"/>`),
                "alt/document.xml": DOC,
            }),
    ],
    [
        "am-f6-orphan-main-typed-part",
        "#437 AM-F6",
        () =>
            buildDocx({
                ...P,
                "alt/document.xml": DOC,
                "[Content_Types].xml": ct(`<Override PartName="/alt/document.xml" ContentType="${MAIN}"/>`),
            }),
    ],
    [
        "am-f6-duplicate-officedoc-same-target",
        "#437 AM-F6",
        () =>
            buildDocx({
                ...P,
                "_rels/.rels": pkgRels(`<Relationship Id="rId9" Type="${REL}/officeDocument" Target="word/document.xml"/>`),
            }),
    ],
    [
        "am-f8-theme-outside-word-malformed",
        "#437 AM-F8",
        () =>
            outsidePart(
                "th/theme1.xml",
                "theme",
                "application/vnd.openxmlformats-officedocument.theme+xml",
                unclosed(
                    `<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="T"><a:themeElements></a:themeElements></a:theme>`,
                ),
                DOC,
            ),
    ],
    [
        "am-f8-glossary-outside-word-malformed",
        "#437 AM-F8",
        () =>
            outsidePart(
                "g/glossary.xml",
                "glossaryDocument",
                `${WML}.document.glossary+xml`,
                unclosed(`<w:glossaryDocument xmlns:w="${W}"><w:docParts></w:docParts></w:glossaryDocument>`),
                DOC,
            ),
    ],
    ["s15d-control-minimal-end", "control", () => buildDocx(P)],
    // s15e — F8: whether Word reads an unused header or endnotes part; F9: the generic types on styles and the main part's text/xml Override.
    ["s15e-control-minimal", "control", () => buildDocx(P)],
    ["am-f8-header-unused-malformed", "#437 AM-F8", () => withPart("header1.xml", "header", `${WML}.header+xml`, unclosed(HEADER))],
    [
        "am-f8-endnotes-unused-malformed",
        "#437 AM-F8",
        () => withPart("endnotes.xml", "endnotes", `${WML}.endnotes+xml`, unclosed(ENDNOTES)),
    ],
    [
        "am-f9-styles-override-appxml",
        "#432 AM-F9",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    `<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml"/>`,
                    `<Override PartName="/word/styles.xml" ContentType="application/xml"/>`,
                ),
            }),
    ],
    [
        "am-f9-styles-default-textxml",
        "#432 AM-F9",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    `<Default Extension="xml" ContentType="application/xml"/>`,
                    `<Default Extension="xml" ContentType="text/xml"/>`,
                ).replace(`<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml"/>`, ""),
            }),
    ],
    [
        "am-f9-main-override-textxml",
        "#432 AM-F9",
        () =>
            buildDocx({
                ...P,
                "[Content_Types].xml": CT.replace(
                    `<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`,
                    `<Override PartName="/word/document.xml" ContentType="text/xml"/>`,
                ),
            }),
    ],
    ["s15e-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 16's builder (`s16a`, `s16b`) is another standalone script, run the same way; each chunk was built with `ONLY=<its specimens>`:

```ts
// Session 16 (2026-10-24): review AR's suspected false negatives of layers 89-92 (#516, #504/#517) and the shapes of its F1 (#535):
// whether Word reads a header or endnotes part referenced only from another story, how it treats a MIME parameter on a part's
// content type, and how it opens a main part stored as .bin or under docProps/ typed by a text/xml Default.
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s16builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const MAIN = `${WML}.document.main+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
const PKG_RELS = P["_rels/.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;

// --- AR suspected: an endnote referenced only from a footnote ---
const ENDNOTES =
    `<w:endnotes xmlns:w="${W}"><w:endnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:id="1"><w:p><w:r><w:t>Endnote</w:t></w:r></w:p></w:endnote></w:endnotes>`;
const FOOTNOTES_WITH_ENDNOTE_REF =
    `<w:footnotes xmlns:w="${W}"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:id="1"><w:p><w:r><w:t>Footnote</w:t></w:r><w:r><w:endnoteReference w:id="1"/></w:r></w:p></w:footnote></w:footnotes>`;
const footnoteDoc = DOC.replace(`<w:r><w:t>Hello</w:t></w:r>`, `<w:r><w:t>Hello</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r>`);
const endnoteViaFootnote = (endnotes: string) =>
    buildDocx({
        ...P,
        "word/document.xml": footnoteDoc,
        "word/footnotes.xml": FOOTNOTES_WITH_ENDNOTE_REF,
        "word/endnotes.xml": endnotes,
        "word/_rels/document.xml.rels": rels(
            `<Relationship Id="rIdF" Type="${REL}/footnotes" Target="footnotes.xml"/><Relationship Id="rIdE" Type="${REL}/endnotes" Target="endnotes.xml"/>`,
        ),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/footnotes.xml" ContentType="${WML}.footnotes+xml"/><Override PartName="/word/endnotes.xml" ContentType="${WML}.endnotes+xml"/>`,
        ),
    });

// --- AR suspected: a header referenced only from the glossary document ---
const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const GLOSSARY =
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdH"/></w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
const headerViaGlossary = (header: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdH" Type="${REL}/header" Target="header9.xml"/>`),
        "word/glossary/header9.xml": header,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${WML}.document.glossary+xml"/><Override PartName="/word/glossary/header9.xml" ContentType="${WML}.header+xml"/>`,
        ),
    });

// --- AR suspected: a MIME parameter on a part's content type ---
const STYLES_OVERRIDE = `<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml"/>`;
const MAIN_OVERRIDE = `<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`;
const withCt = (from: string, to: string) => {
    if (!CT.includes(from)) throw new Error(`content types lack ${from}`);
    return buildDocx({ ...P, "[Content_Types].xml": CT.replace(from, to) });
};

// --- AR F1 (#535): the main part stored elsewhere, typed by a Default ---
const movedMain = (name: string, defaultExtra: string, xmlDefault: string) => {
    const parts: Record<string, string> = { ...P };
    delete parts["word/document.xml"];
    delete parts["word/_rels/document.xml.rels"];
    parts[name] = DOC;
    parts[`${path.posix.dirname(name)}/_rels/${path.posix.basename(name)}.rels`] = DOC_RELS.replace(
        'Target="styles.xml"',
        'Target="/word/styles.xml"',
    );
    parts["_rels/.rels"] = PKG_RELS.replace("word/document.xml", name);
    parts["[Content_Types].xml"] = CT.replace(MAIN_OVERRIDE, "")
        .replace(`<Default Extension="xml" ContentType="application/xml"/>`, `<Default Extension="xml" ContentType="${xmlDefault}"/>`)
        .replace("</Types>", `${defaultExtra}</Types>`);
    return buildDocx(parts);
};

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s16a — review AR: a header or endnotes part referenced only from another story.
    ["s16a-control-minimal", "control", () => buildDocx(P)],
    ["ar-endnote-ref-in-footnote-malformed", "#516 AR-suspected", () => endnoteViaFootnote(unclosed(ENDNOTES))],
    ["ar-endnote-ref-in-footnote-wellformed-control", "#516 AR-suspected", () => endnoteViaFootnote(ENDNOTES)],
    ["ar-header-ref-in-glossary-malformed", "#516 AR-suspected", () => headerViaGlossary(unclosed(HEADER))],
    ["ar-header-ref-in-glossary-wellformed-control", "#516 AR-suspected", () => headerViaGlossary(HEADER)],
    ["s16a-control-minimal-end", "control", () => buildDocx(P)],
    // s16b — review AR: MIME parameters on content types, and the F1 (#535) main-part shapes.
    ["s16b-control-minimal", "control", () => buildDocx(P)],
    [
        "ar-styles-override-appxml-charset",
        "#517 AR-suspected",
        () => withCt(STYLES_OVERRIDE, `<Override PartName="/word/styles.xml" ContentType="application/xml; charset=utf-8"/>`),
    ],
    [
        "ar-styles-override-proper-charset",
        "#517 AR-suspected",
        () => withCt(STYLES_OVERRIDE, `<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml; charset=utf-8"/>`),
    ],
    [
        "ar-main-override-proper-charset",
        "#517 AR-suspected",
        () => withCt(MAIN_OVERRIDE, `<Override PartName="/word/document.xml" ContentType="${MAIN}; charset=utf-8"/>`),
    ],
    [
        "ar-f1-main-bin-default-textxml",
        "#535 AR-F1",
        () => movedMain("word/document.bin", `<Default Extension="bin" ContentType="text/xml"/>`, "text/xml"),
    ],
    [
        "ar-f1-main-bin-default-maintype-control",
        "#535 AR-F1",
        () => movedMain("word/document.bin", `<Default Extension="bin" ContentType="${MAIN}"/>`, "application/xml"),
    ],
    ["ar-f1-main-docprops-default-textxml", "#535 AR-F1", () => movedMain("docProps/document.xml", "", "text/xml")],
    ["s16b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 17's builder (`s17a`–`s17d`) is another standalone script, run the same way; each chunk was built with `ONLY=<its specimens>`:

```ts
// Session 17 (2026-10-24): the questions session 16 left open for #539 and #540.
// s17a: what Word reads through the glossary document (its own relationships part; a footer, footnotes or an unused header it names).
// s17b: a MIME parameter on the content type of parts other than the main part and styles.
// s17c: case, whitespace and a non-charset parameter on the main and styles content types, and a parameterized generic Default.
// s17d: the s17a controls — footnotes, endnotes and comments the glossary references, malformed and well formed, and its relationships part unreferenced.
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s17builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const MAIN = `${WML}.document.main+xml`;
const STYLES = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

// --- s17a: the glossary document's reach ---
const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const FOOTNOTES =
    `<w:footnotes xmlns:w="${W}"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:id="1"><w:p><w:r><w:t>Footnote</w:t></w:r></w:p></w:footnote></w:footnotes>`;
const glossary = (body: string, sectPr: string) =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p><w:sectPr>${sectPr}</w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
/** A glossary document related from the main part, with its own relationships part and the parts it names. */
const viaGlossary = (o: { glossaryXml: string; glossaryRels: string; parts: Record<string, string>; overrides: string }) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": o.glossaryXml,
        "word/glossary/_rels/document.xml.rels": o.glossaryRels,
        ...o.parts,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${WML}.document.glossary+xml"/>${o.overrides}`,
        ),
    });
const HEADER_OVERRIDE = `<Override PartName="/word/glossary/header9.xml" ContentType="${WML}.header+xml"/>`;
const headerRels = relsPart(`<Relationship Id="rIdH" Type="${REL}/header" Target="header9.xml"/>`);
const headerRef = `<w:headerReference w:type="default" r:id="rIdH"/>`;
const glossaryRelsBroken = (rels: string) =>
    viaGlossary({
        glossaryXml: glossary("", headerRef),
        glossaryRels: rels,
        parts: { "word/glossary/header9.xml": HEADER },
        overrides: HEADER_OVERRIDE,
    });
const footerViaGlossary = (footer: string) =>
    viaGlossary({
        glossaryXml: glossary("", `<w:footerReference w:type="default" r:id="rIdF"/>`),
        glossaryRels: relsPart(`<Relationship Id="rIdF" Type="${REL}/footer" Target="footer9.xml"/>`),
        parts: { "word/glossary/footer9.xml": footer },
        overrides: `<Override PartName="/word/glossary/footer9.xml" ContentType="${WML}.footer+xml"/>`,
    });

// --- s17b and s17c: content types with a MIME parameter, case or whitespace ---
const withCt = (from: string, to: string, extraParts: Record<string, string> = {}, extraRels = "", extraCt = "") =>
    buildDocx({
        ...P,
        ...extraParts,
        "word/_rels/document.xml.rels": rels(extraRels),
        "[Content_Types].xml": replaceOnce(ct(extraCt), from, to),
    });
const MAIN_OVERRIDE = `<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`;
const STYLES_OVERRIDE = `<Override PartName="/word/styles.xml" ContentType="${STYLES}"/>`;
/** A settings, fontTable or webSettings part, related from the main part, its Override carrying `contentType`. */
const docPart = (segment: string, file: string, root: string, contentType: string) =>
    buildDocx({
        ...P,
        [`word/${file}`]: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:${root} xmlns:w="${W}"/>`,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${segment}" Target="${file}"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/${file}" ContentType="${contentType}"/>`),
    });
const settingsType = `${WML}.settings+xml`;
const headerInMain = (contentType: string) =>
    buildDocx({
        ...P,
        "word/document.xml": replaceOnce(
            replaceOnce(DOC, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:sectPr>",
            `<w:sectPr>${headerRef}`,
        ),
        "word/header9.xml": HEADER,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdH" Type="${REL}/header" Target="header9.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/header9.xml" ContentType="${contentType}"/>`),
    });

// --- s17d: notes and comments the glossary references ---
const ENDNOTES =
    `<w:endnotes xmlns:w="${W}"><w:endnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:id="1"><w:p><w:r><w:t>Endnote</w:t></w:r></w:p></w:endnote></w:endnotes>`;
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
/** A story part the glossary references from its body, through its own relationships part. */
const storyViaGlossary = (segment: string, file: string, xml: string, reference: string) =>
    viaGlossary({
        glossaryXml: glossary(reference, ""),
        glossaryRels: relsPart(`<Relationship Id="rIdS" Type="${REL}/${segment}" Target="${file}"/>`),
        parts: { [`word/glossary/${file}`]: xml },
        overrides: `<Override PartName="/word/glossary/${file}" ContentType="${WML}.${segment}+xml"/>`,
    });
const footnoteRef = `<w:r><w:footnoteReference w:id="1"/></w:r>`;
const endnoteRef = `<w:r><w:endnoteReference w:id="1"/></w:r>`;
const commentRef = `<w:r><w:commentReference w:id="0"/></w:r>`;

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s17a — #539: what Word reads through the glossary document.
    ["s17a-control-minimal", "control", () => buildDocx(P)],
    ["glossary-rels-unclosed", "#539 open question", () => glossaryRelsBroken(unclosed(headerRels))],
    ["glossary-rels-zero-byte", "#539 open question", () => glossaryRelsBroken("")],
    ["footer-ref-in-glossary-malformed", "#539 open question", () => footerViaGlossary(unclosed(FOOTER))],
    ["footer-ref-in-glossary-wellformed-control", "#539 open question", () => footerViaGlossary(FOOTER)],
    [
        "footnotes-ref-in-glossary-malformed",
        "#539 open question",
        () =>
            viaGlossary({
                glossaryXml: glossary(`<w:r><w:footnoteReference w:id="1"/></w:r>`, ""),
                glossaryRels: relsPart(`<Relationship Id="rIdN" Type="${REL}/footnotes" Target="footnotes.xml"/>`),
                parts: { "word/glossary/footnotes.xml": unclosed(FOOTNOTES) },
                overrides: `<Override PartName="/word/glossary/footnotes.xml" ContentType="${WML}.footnotes+xml"/>`,
            }),
    ],
    [
        "header-related-from-glossary-unused-malformed",
        "#539 open question",
        () =>
            viaGlossary({
                glossaryXml: glossary("", ""),
                glossaryRels: headerRels,
                parts: { "word/glossary/header9.xml": unclosed(HEADER) },
                overrides: HEADER_OVERRIDE,
            }),
    ],
    ["s17a-control-minimal-end", "control", () => buildDocx(P)],
    // s17b — #540: a MIME parameter on parts other than the main part and styles.
    ["s17b-control-minimal", "control", () => buildDocx(P)],
    ["settings-override-proper-control", "#540 open question", () => docPart("settings", "settings.xml", "settings", settingsType)],
    [
        "settings-override-proper-charset",
        "#540 open question",
        () => docPart("settings", "settings.xml", "settings", `${settingsType}; charset=utf-8`),
    ],
    [
        "fonttable-override-proper-charset",
        "#540 open question",
        () => docPart("fontTable", "fontTable.xml", "fonts", `${WML}.fontTable+xml; charset=utf-8`),
    ],
    [
        "websettings-override-proper-charset",
        "#540 open question",
        () => docPart("webSettings", "webSettings.xml", "webSettings", `${WML}.webSettings+xml; charset=utf-8`),
    ],
    ["header-override-proper-charset", "#540 open question", () => headerInMain(`${WML}.header+xml; charset=utf-8`)],
    ["header-override-proper-control", "#540 open question", () => headerInMain(`${WML}.header+xml`)],
    ["s17b-control-minimal-end", "control", () => buildDocx(P)],
    // s17c — #540: case, whitespace and other parameters on the main and styles content types.
    ["s17c-control-minimal", "control", () => buildDocx(P)],
    [
        "main-override-uppercase-type",
        "#540 open question",
        () => withCt(MAIN_OVERRIDE, `<Override PartName="/word/document.xml" ContentType="${MAIN.toUpperCase()}"/>`),
    ],
    [
        "styles-override-uppercase-type",
        "#540 open question",
        () => withCt(STYLES_OVERRIDE, `<Override PartName="/word/styles.xml" ContentType="${STYLES.toUpperCase()}"/>`),
    ],
    [
        "styles-override-trailing-space",
        "#540 open question",
        () => withCt(STYLES_OVERRIDE, `<Override PartName="/word/styles.xml" ContentType="${STYLES} "/>`),
    ],
    [
        "main-override-proper-charset-nospace",
        "#540 open question",
        () => withCt(MAIN_OVERRIDE, `<Override PartName="/word/document.xml" ContentType="${MAIN};charset=utf-8"/>`),
    ],
    [
        "main-override-proper-other-param",
        "#540 open question",
        () => withCt(MAIN_OVERRIDE, `<Override PartName="/word/document.xml" ContentType="${MAIN}; foo=bar"/>`),
    ],
    [
        "styles-default-appxml-charset",
        "#540 open question",
        () =>
            withCt(
                `<Default Extension="xml" ContentType="application/xml"/>${MAIN_OVERRIDE}${STYLES_OVERRIDE}`,
                `<Default Extension="xml" ContentType="application/xml; charset=utf-8"/>${MAIN_OVERRIDE}`,
            ),
    ],
    ["s17c-control-minimal-end", "control", () => buildDocx(P)],
    // s17d — #539: the s17a controls.
    ["s17d-control-minimal", "control", () => buildDocx(P)],
    [
        "footnotes-ref-in-glossary-wellformed-control",
        "#539 open question",
        () => storyViaGlossary("footnotes", "footnotes.xml", FOOTNOTES, footnoteRef),
    ],
    [
        "endnotes-ref-in-glossary-malformed",
        "#539 open question",
        () => storyViaGlossary("endnotes", "endnotes.xml", unclosed(ENDNOTES), endnoteRef),
    ],
    [
        "endnotes-ref-in-glossary-wellformed-control",
        "#539 open question",
        () => storyViaGlossary("endnotes", "endnotes.xml", ENDNOTES, endnoteRef),
    ],
    [
        "comments-ref-in-glossary-malformed",
        "#539 open question",
        () => storyViaGlossary("comments", "comments.xml", unclosed(COMMENTS), commentRef),
    ],
    [
        "comments-ref-in-glossary-wellformed-control",
        "#539 open question",
        () => storyViaGlossary("comments", "comments.xml", COMMENTS, commentRef),
    ],
    [
        "glossary-rels-unclosed-unreferenced",
        "#539 open question",
        () =>
            viaGlossary({
                glossaryXml: glossary("", ""),
                glossaryRels: unclosed(headerRels),
                parts: { "word/glossary/header9.xml": HEADER },
                overrides: HEADER_OVERRIDE,
            }),
    ],
    ["s17d-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 18's builder (`s18a`) is another standalone script, run the same way:

```ts
// Session 18 (2026-10-24): review AS's S3 — word-valid refuses stored names that differ only by Unicode normalization
// (NFC vs NFD) on Word-folding grounds (#441), but no Word observation backs it. Case-only pairs are observed (#351).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s18builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const P = MINIMAL_PARTS as Record<string, string>;
const X = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<x/>`;
const NFC = "café";
const NFD = "café";
/** The minimal package plus unreferenced well-formed XML parts at `names` (typed by the generic xml Default). */
const withParts = (...names: string[]) => buildDocx({ ...P, ...Object.fromEntries(names.map((name) => [name, X])) });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s18a-control-minimal", "control", () => buildDocx(P)],
    ["nfc-name-alone", "S3 calibration", () => withParts(`word/${NFC}.xml`)],
    ["nfd-name-alone", "S3 calibration", () => withParts(`word/${NFD}.xml`)],
    ["nfc-nfd-part-pair", "#441 S3", () => withParts(`word/${NFC}.xml`, `word/${NFD}.xml`)],
    ["nfc-nfd-folder-pair", "#441 S3", () => withParts(`word/${NFC}/a.xml`, `word/${NFD}/b.xml`)],
    ["case-part-pair-control", "#351 control", () => withParts("word/extra.xml", "word/EXTRA.xml")],
    ["s18a-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 19's builder (`s19a`, `s19b`) is another standalone script, run the same way:

```ts
// Session 19 (2026-10-24): #549 made a reached glossary a second story root for its relationships part and the five lazy
// story types, but left the glossary's eagerly parsed relationships (styles, settings, fontTable, webSettings, numbering)
// unfollowed as unobserved. Real Word glossaries carry their own styles, settings, fontTable and webSettings parts.
// Does Word read them at open — does a malformed one get a repair offer?
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s19builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;

// A glossary that references no story: only its eager relationships can reach a part.
const GLOSSARY =
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;

/** Each eager type: relationship segment, stored file under word/glossary/, content type, and a well-formed part. */
const EAGER = {
    styles: { file: "styles.xml", type: `${WML}.styles+xml`, xml: `<w:styles xmlns:w="${W}"></w:styles>` },
    settings: { file: "settings.xml", type: `${WML}.settings+xml`, xml: `<w:settings xmlns:w="${W}"></w:settings>` },
    fontTable: { file: "fontTable.xml", type: `${WML}.fontTable+xml`, xml: `<w:fonts xmlns:w="${W}"></w:fonts>` },
    webSettings: { file: "webSettings.xml", type: `${WML}.webSettings+xml`, xml: `<w:webSettings xmlns:w="${W}"></w:webSettings>` },
    numbering: { file: "numbering.xml", type: `${WML}.numbering+xml`, xml: `<w:numbering xmlns:w="${W}"></w:numbering>` },
} as const;
type Eager = keyof typeof EAGER;

/** The minimal package plus a glossary whose own relationships part relates one `segment` part, malformed or not. */
const glossaryWithEager = (segment: Eager, malformed: boolean) => {
    const { file, type, xml } = EAGER[segment];
    return buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${file}"/>`),
        [`word/glossary/${file}`]: malformed ? unclosed(xml) : xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${WML}.document.glossary+xml"/><Override PartName="/word/glossary/${file}" ContentType="${type}"/>`,
        ),
    });
};

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s19a — a malformed eager part related from a reached glossary.
    ["s19a-control-minimal", "control", () => buildDocx(P)],
    ["glossary-styles-malformed", "#549 eager", () => glossaryWithEager("styles", true)],
    ["glossary-styles-wellformed-control", "#549 eager", () => glossaryWithEager("styles", false)],
    ["glossary-settings-malformed", "#549 eager", () => glossaryWithEager("settings", true)],
    ["glossary-fonttable-malformed", "#549 eager", () => glossaryWithEager("fontTable", true)],
    ["glossary-websettings-malformed", "#549 eager", () => glossaryWithEager("webSettings", true)],
    ["s19a-control-minimal-end", "control", () => buildDocx(P)],
    // s19b — numbering, and the well-formed controls of the other eager types.
    ["s19b-control-minimal", "control", () => buildDocx(P)],
    ["glossary-numbering-malformed", "#549 eager", () => glossaryWithEager("numbering", true)],
    ["glossary-numbering-wellformed-control", "#549 eager", () => glossaryWithEager("numbering", false)],
    ["glossary-settings-wellformed-control", "#549 eager", () => glossaryWithEager("settings", false)],
    ["glossary-fonttable-wellformed-control", "#549 eager", () => glossaryWithEager("fontTable", false)],
    ["glossary-websettings-wellformed-control", "#549 eager", () => glossaryWithEager("webSettings", false)],
    ["s19b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 20's builder (`s20a`–`s20d`) is another standalone script, run the same way:

```ts
// Session 20 (2026-10-24): the "still to be observed" items of docs/plans/evidence/word-probes-2026-10-24.md that the
// current lanes leave open.
// s20a (#562): customXml, theme and a nested glossaryDocument related from a reached glossary, malformed and well formed.
// s20b (#550): a parameterized content type (`; charset=utf-8`) on numbering, theme, glossary, footer, footnotes, endnotes.
// s20c (#550, #549, #432): the same on comments; footnotes/endnotes/comments a glossary relates but does not reference,
//       malformed; numbering and theme typed by the generic Default.
// s20d: the s20b/s20c controls — each part with its exact type.
// The well-formed theme is word/theme/theme1.xml of tests/fixtures/working/package.word-anchor-open-repaired.docx
// (read from the fixture byte for byte, below; the fixture is not modified).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s20builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
// The probed theme: `word/theme/theme1.xml` of a checked-in fixture, byte for byte (the CRLF after its XML declaration included).
const THEME_FIXTURE = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.word-anchor-open-repaired.docx"));
const THEME = await THEME_FIXTURE.file("word/theme/theme1.xml")!.async("string");
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const notes = (kind: "footnote" | "endnote") =>
    `<w:${kind}s xmlns:w="${W}"><w:${kind} w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:${kind}></w:${kind}s>`;
const FOOTNOTES = notes("footnote");
const ENDNOTES = notes("endnote");
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A" w:initials="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const NUMBERING =
    `<w:numbering xmlns:w="${W}"><w:abstractNum w:abstractNumId="0"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/>` +
    `<w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num></w:numbering>`;
const glossary = (body = "") =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;

/** The minimal package plus a reached glossary whose own relationships part relates `segment` -> `target` (`stored`). */
const glossaryRelating = (segment: string, target: string, stored: string, xml: string, override: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossary(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${target}"/>`),
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${override}`),
    });
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

/** The main document with `r` declared, `run` added after the Hello run, and `sectPr` children prepended. */
const docWith = (run: string, sect = "") =>
    replaceOnce(
        replaceOnce(
            replaceOnce(DOC, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:t>Hello</w:t></w:r>",
            `<w:t>Hello</w:t></w:r>${run}`,
        ),
        "<w:sectPr>",
        `<w:sectPr>${sect}`,
    );
/** A part the main document relates (and uses, through `doc`), typed by an Override with `type`, or by the Default when `type` is undefined. */
const mainPart = (o: { segment: string; file: string; xml: string; type: string | undefined; doc?: string }) =>
    buildDocx({
        ...P,
        "word/document.xml": o.doc ?? DOC,
        [`word/${o.file}`]: o.xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${o.segment}" Target="${o.file}"/>`),
        "[Content_Types].xml": o.type === undefined ? CT : ct(ov(`word/${o.file}`, o.type)),
    });
const USED = {
    numbering: { segment: "numbering", file: "numbering.xml", xml: NUMBERING, type: `${WML}.numbering+xml` },
    theme: { segment: "theme", file: "theme/theme1.xml", xml: THEME, type: THEME_TYPE },
    glossary: { segment: "glossaryDocument", file: "glossary/document.xml", xml: glossary(), type: GLOSSARY_TYPE },
    footer: {
        segment: "footer",
        file: "footer9.xml",
        xml: FOOTER,
        type: `${WML}.footer+xml`,
        doc: docWith("", `<w:footerReference w:type="default" r:id="rIdX"/>`),
    },
    footnotes: {
        segment: "footnotes",
        file: "footnotes.xml",
        xml: FOOTNOTES,
        type: `${WML}.footnotes+xml`,
        doc: docWith(`<w:r><w:footnoteReference w:id="1"/></w:r>`),
    },
    endnotes: {
        segment: "endnotes",
        file: "endnotes.xml",
        xml: ENDNOTES,
        type: `${WML}.endnotes+xml`,
        doc: docWith(`<w:r><w:endnoteReference w:id="1"/></w:r>`),
    },
    comments: {
        segment: "comments",
        file: "comments.xml",
        xml: COMMENTS,
        type: `${WML}.comments+xml`,
        doc: docWith(`<w:r><w:commentReference w:id="0"/></w:r>`),
    },
} as const;
type Used = keyof typeof USED;
const charset = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + CHARSET });
const exact = (k: Used) => mainPart({ ...USED[k] });
const generic = (k: Used) => mainPart({ ...USED[k], type: undefined });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s20a — #562: the glossary's unobserved eager relationships.
    ["s20a-control-minimal", "control", () => buildDocx(P)],
    [
        "glossary-customxml-malformed",
        "#562",
        () => glossaryRelating("customXml", "../../customXml/item1.xml", "customXml/item1.xml", unclosed(P["word/styles.xml"]), ""),
    ],
    [
        "glossary-customxml-wellformed-control",
        "#562",
        () => glossaryRelating("customXml", "../../customXml/item1.xml", "customXml/item1.xml", `<root/>`, ""),
    ],
    [
        "glossary-theme-malformed",
        "#562",
        () =>
            glossaryRelating(
                "theme",
                "theme/theme1.xml",
                "word/glossary/theme/theme1.xml",
                unclosed(THEME),
                ov("word/glossary/theme/theme1.xml", THEME_TYPE),
            ),
    ],
    [
        "glossary-theme-wellformed-control",
        "#562",
        () =>
            glossaryRelating(
                "theme",
                "theme/theme1.xml",
                "word/glossary/theme/theme1.xml",
                THEME,
                ov("word/glossary/theme/theme1.xml", THEME_TYPE),
            ),
    ],
    [
        "glossary-nested-glossary-malformed",
        "#562",
        () =>
            glossaryRelating(
                "glossaryDocument",
                "glossary2.xml",
                "word/glossary/glossary2.xml",
                unclosed(glossary()),
                ov("word/glossary/glossary2.xml", GLOSSARY_TYPE),
            ),
    ],
    [
        "glossary-nested-glossary-wellformed-control",
        "#562",
        () =>
            glossaryRelating(
                "glossaryDocument",
                "glossary2.xml",
                "word/glossary/glossary2.xml",
                glossary(),
                ov("word/glossary/glossary2.xml", GLOSSARY_TYPE),
            ),
    ],
    ["s20a-control-minimal-end", "control", () => buildDocx(P)],
    // s20b — #550: a MIME parameter on the remaining Word-read part types.
    ["s20b-control-minimal", "control", () => buildDocx(P)],
    ["numbering-override-charset", "#550", () => charset("numbering")],
    ["theme-override-charset", "#550", () => charset("theme")],
    ["glossary-override-charset", "#550", () => charset("glossary")],
    ["footer-override-charset", "#550", () => charset("footer")],
    ["footnotes-override-charset", "#550", () => charset("footnotes")],
    ["endnotes-override-charset", "#550", () => charset("endnotes")],
    ["s20b-control-minimal-end", "control", () => buildDocx(P)],
    // s20c — #550 comments; #549 stories a glossary relates but does not reference; #432 generic Default.
    ["s20c-control-minimal", "control", () => buildDocx(P)],
    ["comments-override-charset", "#550", () => charset("comments")],
    [
        "glossary-footnotes-related-unreferenced-malformed",
        "#549",
        () =>
            glossaryRelating(
                "footnotes",
                "footnotes.xml",
                "word/glossary/footnotes.xml",
                unclosed(FOOTNOTES),
                ov("word/glossary/footnotes.xml", `${WML}.footnotes+xml`),
            ),
    ],
    [
        "glossary-endnotes-related-unreferenced-malformed",
        "#549",
        () =>
            glossaryRelating(
                "endnotes",
                "endnotes.xml",
                "word/glossary/endnotes.xml",
                unclosed(ENDNOTES),
                ov("word/glossary/endnotes.xml", `${WML}.endnotes+xml`),
            ),
    ],
    [
        "glossary-comments-related-unreferenced-malformed",
        "#549",
        () =>
            glossaryRelating(
                "comments",
                "comments.xml",
                "word/glossary/comments.xml",
                unclosed(COMMENTS),
                ov("word/glossary/comments.xml", `${WML}.comments+xml`),
            ),
    ],
    ["numbering-default-generic", "#432", () => generic("numbering")],
    ["theme-default-generic", "#432", () => generic("theme")],
    ["s20c-control-minimal-end", "control", () => buildDocx(P)],
    // s20d — the exact-type controls of s20b and s20c.
    ["s20d-control-minimal", "control", () => buildDocx(P)],
    ["numbering-override-exact-control", "#550 #432 control", () => exact("numbering")],
    ["theme-override-exact-control", "#550 #432 control", () => exact("theme")],
    ["glossary-override-exact-control", "#550 control", () => exact("glossary")],
    ["footer-override-exact-control", "#550 control", () => exact("footer")],
    ["footnotes-override-exact-control", "#550 control", () => exact("footnotes")],
    ["endnotes-override-exact-control", "#550 control", () => exact("endnotes")],
    ["comments-override-exact-control", "#550 control", () => exact("comments")],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 21's builder (`s21a`–`s21b`) is another standalone script, run the same way:

```ts
// Session 21 (2026-10-24): what session 20 left open for #570.
// s21a: a padded content type (the part's own type plus a trailing space) on numbering, theme, and a used footer,
//       footnotes, endnotes and comments.
// s21b: `; charset=utf-8` on a related but UNUSED footer, footnotes, endnotes, comments and header; and on the styles part a
//       reached glossary relates (session 19 observed that part is read), with its exact-type control.
// Built from the session 20 builder's helpers. Run from the stack worktree root as a copy:
// BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s21builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
// The probed theme: `word/theme/theme1.xml` of a checked-in fixture, byte for byte (the CRLF after its XML declaration included).
const THEME_FIXTURE = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.word-anchor-open-repaired.docx"));
const THEME = await THEME_FIXTURE.file("word/theme/theme1.xml")!.async("string");
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const notes = (kind: "footnote" | "endnote") =>
    `<w:${kind}s xmlns:w="${W}"><w:${kind} w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:${kind}></w:${kind}s>`;
const FOOTNOTES = notes("footnote");
const ENDNOTES = notes("endnote");
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A" w:initials="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const NUMBERING =
    `<w:numbering xmlns:w="${W}"><w:abstractNum w:abstractNumId="0"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/>` +
    `<w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num></w:numbering>`;
const glossary = (body = "") =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;

/** The minimal package plus a reached glossary whose own relationships part relates `segment` -> `target` (`stored`). */
const glossaryRelating = (segment: string, target: string, stored: string, xml: string, override: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossary(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${target}"/>`),
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${override}`),
    });
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

/** The main document with `r` declared, `run` added after the Hello run, and `sectPr` children prepended. */
const docWith = (run: string, sect = "") =>
    replaceOnce(
        replaceOnce(
            replaceOnce(DOC, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:t>Hello</w:t></w:r>",
            `<w:t>Hello</w:t></w:r>${run}`,
        ),
        "<w:sectPr>",
        `<w:sectPr>${sect}`,
    );
/** A part the main document relates (and uses, through `doc`), typed by an Override with `type`, or by the Default when `type` is undefined. */
const mainPart = (o: { segment: string; file: string; xml: string; type: string | undefined; doc?: string }) =>
    buildDocx({
        ...P,
        "word/document.xml": o.doc ?? DOC,
        [`word/${o.file}`]: o.xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${o.segment}" Target="${o.file}"/>`),
        "[Content_Types].xml": o.type === undefined ? CT : ct(ov(`word/${o.file}`, o.type)),
    });
const USED = {
    numbering: { segment: "numbering", file: "numbering.xml", xml: NUMBERING, type: `${WML}.numbering+xml` },
    theme: { segment: "theme", file: "theme/theme1.xml", xml: THEME, type: THEME_TYPE },
    glossary: { segment: "glossaryDocument", file: "glossary/document.xml", xml: glossary(), type: GLOSSARY_TYPE },
    footer: {
        segment: "footer",
        file: "footer9.xml",
        xml: FOOTER,
        type: `${WML}.footer+xml`,
        doc: docWith("", `<w:footerReference w:type="default" r:id="rIdX"/>`),
    },
    footnotes: {
        segment: "footnotes",
        file: "footnotes.xml",
        xml: FOOTNOTES,
        type: `${WML}.footnotes+xml`,
        doc: docWith(`<w:r><w:footnoteReference w:id="1"/></w:r>`),
    },
    endnotes: {
        segment: "endnotes",
        file: "endnotes.xml",
        xml: ENDNOTES,
        type: `${WML}.endnotes+xml`,
        doc: docWith(`<w:r><w:endnoteReference w:id="1"/></w:r>`),
    },
    comments: {
        segment: "comments",
        file: "comments.xml",
        xml: COMMENTS,
        type: `${WML}.comments+xml`,
        doc: docWith(`<w:r><w:commentReference w:id="0"/></w:r>`),
    },
} as const;
type Used = keyof typeof USED;
const charset = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + CHARSET });
const exact = (k: Used) => mainPart({ ...USED[k] });
const generic = (k: Used) => mainPart({ ...USED[k], type: undefined });

const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const STYLES_TYPE = `${WML}.styles+xml`;
const GLOSSARY_STYLES = `<w:styles xmlns:w="${W}"></w:styles>`;
const padded = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + " " });
/** The part related from the main document but not used: no reference, the main document unchanged. */
const unused = (segment: string, file: string, xml: string, type: string) => mainPart({ segment, file, xml, type: type + CHARSET });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s21a — #570: a trailing space after the part's own type.
    ["s21a-control-minimal", "control", () => buildDocx(P)],
    ["numbering-override-padded", "#570", () => padded("numbering")],
    ["theme-override-padded", "#570", () => padded("theme")],
    ["footer-override-padded", "#570", () => padded("footer")],
    ["footnotes-override-padded", "#570", () => padded("footnotes")],
    ["endnotes-override-padded", "#570", () => padded("endnotes")],
    ["comments-override-padded", "#570", () => padded("comments")],
    ["s21a-control-minimal-end", "control", () => buildDocx(P)],
    // s21b — #570: a parameterized type on related but unused lazy parts; and on a glossary's own styles part.
    ["s21b-control-minimal", "control", () => buildDocx(P)],
    ["footer-unused-override-charset", "#570", () => unused("footer", "footer9.xml", FOOTER, `${WML}.footer+xml`)],
    ["footnotes-unused-override-charset", "#570", () => unused("footnotes", "footnotes.xml", FOOTNOTES, `${WML}.footnotes+xml`)],
    ["endnotes-unused-override-charset", "#570", () => unused("endnotes", "endnotes.xml", ENDNOTES, `${WML}.endnotes+xml`)],
    ["comments-unused-override-charset", "#570", () => unused("comments", "comments.xml", COMMENTS, `${WML}.comments+xml`)],
    ["header-unused-override-charset", "#570", () => unused("header", "header9.xml", HEADER, `${WML}.header+xml`)],
    [
        "glossary-styles-override-charset",
        "#570 #562",
        () =>
            glossaryRelating(
                "styles",
                "styles.xml",
                "word/glossary/styles.xml",
                GLOSSARY_STYLES,
                ov("word/glossary/styles.xml", STYLES_TYPE + CHARSET),
            ),
    ],
    [
        "glossary-styles-override-exact-control",
        "#570 #562 control",
        () =>
            glossaryRelating(
                "styles",
                "styles.xml",
                "word/glossary/styles.xml",
                GLOSSARY_STYLES,
                ov("word/glossary/styles.xml", STYLES_TYPE),
            ),
    ],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 22's builder (`s22a`–`s22b`) is another standalone script, run the same way:

```ts
// Session 22 (2026-10-24): the suspected items adversarial review AU (layer 109) left for a Word probe.
// s22a: S1 — an inexact type on a header a reached glossary references; S6 — a glossary header referenced only from an
//       unselected mc:Fallback, with the selected-Choice control.
// s22b: S2 — an empty main-document Override ContentType; S4 — styles type plus a trailing NO-BREAK SPACE (U+00A0), with the
//       ASCII-space control; S5 — the upper-case main type plus an upper-case parameter, with the upper-case-only control.
// Built from the session 21 builder's helpers. Run from the stack worktree root as a copy:
// BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s22builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
// The probed theme: `word/theme/theme1.xml` of a checked-in fixture, byte for byte (the CRLF after its XML declaration included).
const THEME_FIXTURE = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.word-anchor-open-repaired.docx"));
const THEME = await THEME_FIXTURE.file("word/theme/theme1.xml")!.async("string");
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const notes = (kind: "footnote" | "endnote") =>
    `<w:${kind}s xmlns:w="${W}"><w:${kind} w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:${kind}></w:${kind}s>`;
const FOOTNOTES = notes("footnote");
const ENDNOTES = notes("endnote");
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A" w:initials="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const NUMBERING =
    `<w:numbering xmlns:w="${W}"><w:abstractNum w:abstractNumId="0"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/>` +
    `<w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num></w:numbering>`;
const glossary = (body = "") =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;

/** The minimal package plus a reached glossary whose own relationships part relates `segment` -> `target` (`stored`). */
const glossaryRelating = (segment: string, target: string, stored: string, xml: string, override: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossary(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${target}"/>`),
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${override}`),
    });
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

/** The main document with `r` declared, `run` added after the Hello run, and `sectPr` children prepended. */
const docWith = (run: string, sect = "") =>
    replaceOnce(
        replaceOnce(
            replaceOnce(DOC, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:t>Hello</w:t></w:r>",
            `<w:t>Hello</w:t></w:r>${run}`,
        ),
        "<w:sectPr>",
        `<w:sectPr>${sect}`,
    );
/** A part the main document relates (and uses, through `doc`), typed by an Override with `type`, or by the Default when `type` is undefined. */
const mainPart = (o: { segment: string; file: string; xml: string; type: string | undefined; doc?: string }) =>
    buildDocx({
        ...P,
        "word/document.xml": o.doc ?? DOC,
        [`word/${o.file}`]: o.xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${o.segment}" Target="${o.file}"/>`),
        "[Content_Types].xml": o.type === undefined ? CT : ct(ov(`word/${o.file}`, o.type)),
    });
const USED = {
    numbering: { segment: "numbering", file: "numbering.xml", xml: NUMBERING, type: `${WML}.numbering+xml` },
    theme: { segment: "theme", file: "theme/theme1.xml", xml: THEME, type: THEME_TYPE },
    glossary: { segment: "glossaryDocument", file: "glossary/document.xml", xml: glossary(), type: GLOSSARY_TYPE },
    footer: {
        segment: "footer",
        file: "footer9.xml",
        xml: FOOTER,
        type: `${WML}.footer+xml`,
        doc: docWith("", `<w:footerReference w:type="default" r:id="rIdX"/>`),
    },
    footnotes: {
        segment: "footnotes",
        file: "footnotes.xml",
        xml: FOOTNOTES,
        type: `${WML}.footnotes+xml`,
        doc: docWith(`<w:r><w:footnoteReference w:id="1"/></w:r>`),
    },
    endnotes: {
        segment: "endnotes",
        file: "endnotes.xml",
        xml: ENDNOTES,
        type: `${WML}.endnotes+xml`,
        doc: docWith(`<w:r><w:endnoteReference w:id="1"/></w:r>`),
    },
    comments: {
        segment: "comments",
        file: "comments.xml",
        xml: COMMENTS,
        type: `${WML}.comments+xml`,
        doc: docWith(`<w:r><w:commentReference w:id="0"/></w:r>`),
    },
} as const;
type Used = keyof typeof USED;
const charset = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + CHARSET });
const exact = (k: Used) => mainPart({ ...USED[k] });
const generic = (k: Used) => mainPart({ ...USED[k], type: undefined });

const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const STYLES_TYPE = `${WML}.styles+xml`;
const GLOSSARY_STYLES = `<w:styles xmlns:w="${W}"></w:styles>`;
const padded = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + " " });
/** The part related from the main document but not used: no reference, the main document unchanged. */
const unused = (segment: string, file: string, xml: string, type: string) => mainPart({ segment, file, xml, type: type + CHARSET });

const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const MAIN = `${WML}.document.main+xml`;
const MAIN_OVERRIDE = `<Override PartName="/word/document.xml" ContentType="${MAIN}"/>`;
const STYLES_OVERRIDE = `<Override PartName="/word/styles.xml" ContentType="${STYLES_TYPE}"/>`;
const withCt = (from: string, to: string) => buildDocx({ ...P, "[Content_Types].xml": replaceOnce(CT, from, to) });

/** A glossary whose docPartBody ends with `sectPr`, declaring mc and w14 for the AlternateContent shapes. */
const glossaryWithSect = (sect: string) =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}" xmlns:mc="${MC}" xmlns:w14="${W14}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p><w:sectPr>${sect}</w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
const REF = `<w:headerReference w:type="default" r:id="rIdH"/>`;
/** The session 16 shape: a header only the reached glossary references, typed by `headerType`. */
const headerViaGlossary = (sect: string, header: string, headerType: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossaryWithSect(sect),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdH" Type="${REL}/header" Target="header9.xml"/>`),
        "word/glossary/header9.xml": header,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`${ov("word/glossary/document.xml", GLOSSARY_TYPE)}${ov("word/glossary/header9.xml", headerType)}`),
    });
const HEADER_TYPE = `${WML}.header+xml`;
const alternate = (choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="w14">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s22a — review AU S1 and S6: headers a reached glossary references.
    ["s22a-control-minimal", "control", () => buildDocx(P)],
    ["glossary-header-override-charset", "AU-S1", () => headerViaGlossary(REF, HEADER, HEADER_TYPE + CHARSET)],
    ["glossary-header-override-exact-control", "AU-S1 control", () => headerViaGlossary(REF, HEADER, HEADER_TYPE)],
    ["glossary-header-fallback-only-malformed", "AU-S6", () => headerViaGlossary(alternate("", REF), unclosed(HEADER), HEADER_TYPE)],
    [
        "glossary-header-choice-only-malformed-control",
        "AU-S6 control",
        () => headerViaGlossary(alternate(REF, ""), unclosed(HEADER), HEADER_TYPE),
    ],
    ["glossary-header-fallback-only-wellformed-control", "AU-S6 control", () => headerViaGlossary(alternate("", REF), HEADER, HEADER_TYPE)],
    ["s22a-control-minimal-end", "control", () => buildDocx(P)],
    // s22b — review AU S2, S4, S5: content-type spellings.
    ["s22b-control-minimal", "control", () => buildDocx(P)],
    ["main-override-empty-contenttype", "AU-S2", () => withCt(MAIN_OVERRIDE, `<Override PartName="/word/document.xml" ContentType=""/>`)],
    ["styles-override-nbsp-trailing", "AU-S4", () => withCt(STYLES_OVERRIDE, ov("word/styles.xml", `${STYLES_TYPE} `))],
    [
        "styles-override-ascii-trailing-space-control",
        "AU-S4 control",
        () => withCt(STYLES_OVERRIDE, ov("word/styles.xml", `${STYLES_TYPE} `)),
    ],
    [
        "main-override-upper-charset-upper",
        "AU-S5",
        () => withCt(MAIN_OVERRIDE, ov("word/document.xml", `${MAIN.toUpperCase()}; CHARSET=UTF-8`)),
    ],
    ["main-override-upper-control", "AU-S5 control", () => withCt(MAIN_OVERRIDE, ov("word/document.xml", MAIN.toUpperCase()))],
    ["s22b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 23's builder (`s23a`–`s23b`) is another standalone script, run the same way:

```ts
// Session 23 (2026-10-24): the suspected items adversarial review AW (layers 116–123) left for a Word probe.
// s23a: #595 — a theme only a reached glossary relates, typed by the generic Default, with the exact-Override control;
//       #596 — a charset parameter on a footer and on comments the reached glossary references, with exact controls.
// s23b: #596 — a charset parameter on footnotes and endnotes the reached glossary references, with exact controls.
// The glossary story shapes are session 17's (s17a, s17d); the glossary theme shape is session 20's (#569).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s23builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
// The probed theme: `word/theme/theme1.xml` of a checked-in fixture, byte for byte (the CRLF after its XML declaration included).
const THEME_FIXTURE = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.word-anchor-open-repaired.docx"));
const THEME = await THEME_FIXTURE.file("word/theme/theme1.xml")!.async("string");
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const FOOTNOTES =
    `<w:footnotes xmlns:w="${W}"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:id="1"><w:p><w:r><w:t>Footnote</w:t></w:r></w:p></w:footnote></w:footnotes>`;
const ENDNOTES =
    `<w:endnotes xmlns:w="${W}"><w:endnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:endnote>` +
    `<w:endnote w:id="1"><w:p><w:r><w:t>Endnote</w:t></w:r></w:p></w:endnote></w:endnotes>`;
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const glossary = (body: string, sectPr: string) =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p><w:sectPr>${sectPr}</w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
/** Session 20's glossary (#569): no sectPr, references nothing. */
const glossaryPlain = () =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/** A glossary document related from the main part, with its own relationships part and the parts it names. */
const viaGlossary = (o: { glossaryXml: string; glossaryRels: string; parts: Record<string, string>; overrides: string }) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": o.glossaryXml,
        "word/glossary/_rels/document.xml.rels": o.glossaryRels,
        ...o.parts,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${WML}.document.glossary+xml"/>${o.overrides}`,
        ),
    });
/** #595: the theme only the glossary relates; `override` empty leaves it to the generic `application/xml` Default. */
const glossaryTheme = (override: string) =>
    viaGlossary({
        glossaryXml: glossaryPlain(),
        glossaryRels: relsPart(`<Relationship Id="rIdE" Type="${REL}/theme" Target="theme/theme1.xml"/>`),
        parts: { "word/glossary/theme/theme1.xml": THEME },
        overrides: override,
    });
/** #596: session 17's footer the glossary references from its sectPr, typed `type`. */
const footerViaGlossary = (type: string) =>
    viaGlossary({
        glossaryXml: glossary("", `<w:footerReference w:type="default" r:id="rIdF"/>`),
        glossaryRels: relsPart(`<Relationship Id="rIdF" Type="${REL}/footer" Target="footer9.xml"/>`),
        parts: { "word/glossary/footer9.xml": FOOTER },
        overrides: ov("word/glossary/footer9.xml", type),
    });
/** #596: session 17's story part the glossary references from its body, typed `type`. */
const storyViaGlossary = (segment: string, file: string, xml: string, reference: string, type: string) =>
    viaGlossary({
        glossaryXml: glossary(reference, ""),
        glossaryRels: relsPart(`<Relationship Id="rIdS" Type="${REL}/${segment}" Target="${file}"/>`),
        parts: { [`word/glossary/${file}`]: xml },
        overrides: ov(`word/glossary/${file}`, type),
    });
const footnoteRef = `<w:r><w:footnoteReference w:id="1"/></w:r>`;
const endnoteRef = `<w:r><w:endnoteReference w:id="1"/></w:r>`;
const commentRef = `<w:r><w:commentReference w:id="0"/></w:r>`;
const T = (segment: string) => `${WML}.${segment}+xml`;

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s23a — #595 and #596 (footer, comments).
    ["s23a-control-minimal", "control", () => buildDocx(P)],
    ["glossary-theme-default-generic", "#595", () => glossaryTheme("")],
    ["glossary-theme-override-exact-control", "#595 control", () => glossaryTheme(ov("word/glossary/theme/theme1.xml", THEME_TYPE))],
    ["glossary-footer-ref-override-charset", "#596", () => footerViaGlossary(T("footer") + CHARSET)],
    ["glossary-footer-ref-override-exact-control", "#596 control", () => footerViaGlossary(T("footer"))],
    [
        "glossary-comments-ref-override-charset",
        "#596",
        () => storyViaGlossary("comments", "comments.xml", COMMENTS, commentRef, T("comments") + CHARSET),
    ],
    [
        "glossary-comments-ref-override-exact-control",
        "#596 control",
        () => storyViaGlossary("comments", "comments.xml", COMMENTS, commentRef, T("comments")),
    ],
    ["s23a-control-minimal-end", "control", () => buildDocx(P)],
    // s23b — #596 (footnotes, endnotes).
    ["s23b-control-minimal", "control", () => buildDocx(P)],
    [
        "glossary-footnotes-ref-override-charset",
        "#596",
        () => storyViaGlossary("footnotes", "footnotes.xml", FOOTNOTES, footnoteRef, T("footnotes") + CHARSET),
    ],
    [
        "glossary-footnotes-ref-override-exact-control",
        "#596 control",
        () => storyViaGlossary("footnotes", "footnotes.xml", FOOTNOTES, footnoteRef, T("footnotes")),
    ],
    [
        "glossary-endnotes-ref-override-charset",
        "#596",
        () => storyViaGlossary("endnotes", "endnotes.xml", ENDNOTES, endnoteRef, T("endnotes") + CHARSET),
    ],
    [
        "glossary-endnotes-ref-override-exact-control",
        "#596 control",
        () => storyViaGlossary("endnotes", "endnotes.xml", ENDNOTES, endnoteRef, T("endnotes")),
    ],
    ["s23b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 24's builder (`s24a`–`s24b`) is another standalone script, run the same way:

```ts
// Session 24 (2026-10-24): the suspected items adversarial review AX (layers 124–127) left for a Word probe.
// s24a: SX1 — a story part declared with ANOTHER story's exact content type: a footer the main document references typed
//       header+xml, a header it references typed footer+xml, and a footer a reached glossary references typed header+xml
//       (exact, and with "; charset=utf-8"), each with its own exact-type control.
// s24b: SX2 — a reached glossary's styles part typed only by the generic `application/xml` Default; SX3 — a reached
//       glossary's theme typed `text/xml` by an Override; each with its exact-Override control, plus the glossary-footer control.
// Shapes: main stories as session 20/21 (`mainPart`, `docWith`), glossary styles as s21b, glossary footer and theme as s23a.
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s24builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
// The probed theme: `word/theme/theme1.xml` of a checked-in fixture, byte for byte (the CRLF after its XML declaration included).
const THEME_FIXTURE = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.word-anchor-open-repaired.docx"));
const THEME = await THEME_FIXTURE.file("word/theme/theme1.xml")!.async("string");
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const notes = (kind: "footnote" | "endnote") =>
    `<w:${kind}s xmlns:w="${W}"><w:${kind} w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:${kind}></w:${kind}s>`;
const FOOTNOTES = notes("footnote");
const ENDNOTES = notes("endnote");
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A" w:initials="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const NUMBERING =
    `<w:numbering xmlns:w="${W}"><w:abstractNum w:abstractNumId="0"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/>` +
    `<w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num></w:numbering>`;
const glossary = (body = "") =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;

/** The minimal package plus a reached glossary whose own relationships part relates `segment` -> `target` (`stored`). */
const glossaryRelating = (segment: string, target: string, stored: string, xml: string, override: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossary(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${target}"/>`),
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${override}`),
    });
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

/** The main document with `r` declared, `run` added after the Hello run, and `sectPr` children prepended. */
const docWith = (run: string, sect = "") =>
    replaceOnce(
        replaceOnce(
            replaceOnce(DOC, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:t>Hello</w:t></w:r>",
            `<w:t>Hello</w:t></w:r>${run}`,
        ),
        "<w:sectPr>",
        `<w:sectPr>${sect}`,
    );
/** A part the main document relates (and uses, through `doc`), typed by an Override with `type`, or by the Default when `type` is undefined. */
const mainPart = (o: { segment: string; file: string; xml: string; type: string | undefined; doc?: string }) =>
    buildDocx({
        ...P,
        "word/document.xml": o.doc ?? DOC,
        [`word/${o.file}`]: o.xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${o.segment}" Target="${o.file}"/>`),
        "[Content_Types].xml": o.type === undefined ? CT : ct(ov(`word/${o.file}`, o.type)),
    });
const USED = {
    numbering: { segment: "numbering", file: "numbering.xml", xml: NUMBERING, type: `${WML}.numbering+xml` },
    theme: { segment: "theme", file: "theme/theme1.xml", xml: THEME, type: THEME_TYPE },
    glossary: { segment: "glossaryDocument", file: "glossary/document.xml", xml: glossary(), type: GLOSSARY_TYPE },
    footer: {
        segment: "footer",
        file: "footer9.xml",
        xml: FOOTER,
        type: `${WML}.footer+xml`,
        doc: docWith("", `<w:footerReference w:type="default" r:id="rIdX"/>`),
    },
    footnotes: {
        segment: "footnotes",
        file: "footnotes.xml",
        xml: FOOTNOTES,
        type: `${WML}.footnotes+xml`,
        doc: docWith(`<w:r><w:footnoteReference w:id="1"/></w:r>`),
    },
    endnotes: {
        segment: "endnotes",
        file: "endnotes.xml",
        xml: ENDNOTES,
        type: `${WML}.endnotes+xml`,
        doc: docWith(`<w:r><w:endnoteReference w:id="1"/></w:r>`),
    },
    comments: {
        segment: "comments",
        file: "comments.xml",
        xml: COMMENTS,
        type: `${WML}.comments+xml`,
        doc: docWith(`<w:r><w:commentReference w:id="0"/></w:r>`),
    },
} as const;
type Used = keyof typeof USED;
const charset = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + CHARSET });
const exact = (k: Used) => mainPart({ ...USED[k] });
const generic = (k: Used) => mainPart({ ...USED[k], type: undefined });

const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const STYLES_TYPE = `${WML}.styles+xml`;
const GLOSSARY_STYLES = `<w:styles xmlns:w="${W}"></w:styles>`;
const padded = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + " " });
/** The part related from the main document but not used: no reference, the main document unchanged. */
const unused = (segment: string, file: string, xml: string, type: string) => mainPart({ segment, file, xml, type: type + CHARSET });

const T = (segment: string) => `${WML}.${segment}+xml`;
const HEADER_REF = docWith("", `<w:headerReference w:type="default" r:id="rIdX"/>`);
/** A header the main document references from its sectPr, typed `type`. */
const mainHeader = (type: string) => mainPart({ segment: "header", file: "header9.xml", xml: HEADER, type, doc: HEADER_REF });
/** Session 23's glossary that references footer9.xml from its docPartBody's sectPr. */
const glossaryWithFooterRef = () =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p><w:sectPr><w:footerReference w:type="default" r:id="rIdF"/></w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
const footerViaGlossary = (type: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossaryWithFooterRef(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdF" Type="${REL}/footer" Target="footer9.xml"/>`),
        "word/glossary/footer9.xml": FOOTER,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${ov("word/glossary/footer9.xml", type)}`,
        ),
    });
const glossaryTheme = (override: string) =>
    glossaryRelating("theme", "theme/theme1.xml", "word/glossary/theme/theme1.xml", THEME, override);

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    // s24a — SX1.
    ["s24a-control-minimal", "control", () => buildDocx(P)],
    ["main-footer-typed-header-exact", "SX1", () => mainPart({ ...USED.footer, type: T("header") })],
    ["main-footer-override-exact-control", "SX1 control", () => exact("footer")],
    ["main-header-typed-footer-exact", "SX1", () => mainHeader(T("footer"))],
    ["main-header-override-exact-control", "SX1 control", () => mainHeader(T("header"))],
    ["glossary-footer-typed-header-exact", "SX1", () => footerViaGlossary(T("header"))],
    ["glossary-footer-typed-header-charset", "SX1", () => footerViaGlossary(T("header") + CHARSET)],
    ["s24a-control-minimal-end", "control", () => buildDocx(P)],
    // s24b — SX1's glossary control, SX2, SX3.
    ["s24b-control-minimal", "control", () => buildDocx(P)],
    ["glossary-footer-ref-override-exact-control", "SX1 control", () => footerViaGlossary(T("footer"))],
    [
        "glossary-styles-default-generic",
        "SX2",
        () => glossaryRelating("styles", "styles.xml", "word/glossary/styles.xml", GLOSSARY_STYLES, ""),
    ],
    [
        "glossary-styles-override-exact-control",
        "SX2 control",
        () =>
            glossaryRelating(
                "styles",
                "styles.xml",
                "word/glossary/styles.xml",
                GLOSSARY_STYLES,
                ov("word/glossary/styles.xml", STYLES_TYPE),
            ),
    ],
    ["glossary-theme-override-text-xml", "SX3", () => glossaryTheme(ov("word/glossary/theme/theme1.xml", "text/xml"))],
    ["glossary-theme-override-exact-control", "SX3 control", () => glossaryTheme(ov("word/glossary/theme/theme1.xml", THEME_TYPE))],
    ["s24b-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

The header comments of the session 8–26 builders write the optional filter as `[ONLY=a,b]`: a placeholder, not shell. Run a builder with `BUILD_DIR=<chunk>/src pnpm exec tsx s24builder.tmp.mts`, or filter it to exact specimen names with `BUILD_DIR=<chunk>/src ONLY=main-footer-typed-header-exact,main-footer-override-exact-control pnpm exec tsx s24builder.tmp.mts`. The builders are kept as they ran.

Session 26's builder (`s26a`) is another standalone script, run the same way:

```ts
// Session 26 (2026-10-24): the items adversarial review AY (layer 128, #602) left for a Word probe.
// s26a: S-A — a `w:headerReference` whose r:id names a FOOTER-type relationship to a `w:hdr` part, typed footer+xml
//       (control), footer+xml; charset=utf-8, and header+xml; S-B — a footer the main document reads through a footer
//       relationship that an unused header relationship also targets, typed header+xml, with its footer+xml control;
//       F3 — a header a reached glossary references from its docPartBody's sectPr, typed footer+xml.
// Shapes: as session 24 (`mainPart`, `docWith`, the glossary of session 23 with a header reference instead of a footer one).
// Run from the stack worktree root as a copy: BUILD_DIR=<chunk>/src [ONLY=a,b] pnpm exec tsx s26builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const THEME_TYPE = "application/vnd.openxmlformats-officedocument.theme+xml";
const CHARSET = "; charset=utf-8";
const P = MINIMAL_PARTS as Record<string, string>;
const CT = P["[Content_Types].xml"];
const DOC = P["word/document.xml"];
const DOC_RELS = P["word/_rels/document.xml.rels"];
/** Well formed up to a missing end of the root element: namespaces stay declared, the part does not parse. */
const unclosed = (xml: string) => xml.slice(0, xml.lastIndexOf("</"));
const ct = (extra: string) => CT.replace("</Types>", `${extra}</Types>`);
const rels = (extra: string) => DOC_RELS.replace("</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};

const FOOTER = `<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`;
const notes = (kind: "footnote" | "endnote") =>
    `<w:${kind}s xmlns:w="${W}"><w:${kind} w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}>` +
    `<w:${kind} w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:${kind}></w:${kind}s>`;
const FOOTNOTES = notes("footnote");
const ENDNOTES = notes("endnote");
const COMMENTS = `<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="A" w:initials="A"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;
const NUMBERING =
    `<w:numbering xmlns:w="${W}"><w:abstractNum w:abstractNumId="0"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/>` +
    `<w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num></w:numbering>`;
const glossary = (body = "") =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r>${body}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;

/** The minimal package plus a reached glossary whose own relationships part relates `segment` -> `target` (`stored`). */
const glossaryRelating = (segment: string, target: string, stored: string, xml: string, override: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossary(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdE" Type="${REL}/${segment}" Target="${target}"/>`),
        [stored]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(`<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${override}`),
    });
const ov = (part: string, type: string) => `<Override PartName="/${part}" ContentType="${type}"/>`;

/** The main document with `r` declared, `run` added after the Hello run, and `sectPr` children prepended. */
const docWith = (run: string, sect = "") =>
    replaceOnce(
        replaceOnce(
            replaceOnce(DOC, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:t>Hello</w:t></w:r>",
            `<w:t>Hello</w:t></w:r>${run}`,
        ),
        "<w:sectPr>",
        `<w:sectPr>${sect}`,
    );
/** A part the main document relates (and uses, through `doc`), typed by an Override with `type`, or by the Default when `type` is undefined. */
const mainPart = (o: { segment: string; file: string; xml: string; type: string | undefined; doc?: string }) =>
    buildDocx({
        ...P,
        "word/document.xml": o.doc ?? DOC,
        [`word/${o.file}`]: o.xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdX" Type="${REL}/${o.segment}" Target="${o.file}"/>`),
        "[Content_Types].xml": o.type === undefined ? CT : ct(ov(`word/${o.file}`, o.type)),
    });
const USED = {
    numbering: { segment: "numbering", file: "numbering.xml", xml: NUMBERING, type: `${WML}.numbering+xml` },
    glossary: { segment: "glossaryDocument", file: "glossary/document.xml", xml: glossary(), type: GLOSSARY_TYPE },
    footer: {
        segment: "footer",
        file: "footer9.xml",
        xml: FOOTER,
        type: `${WML}.footer+xml`,
        doc: docWith("", `<w:footerReference w:type="default" r:id="rIdX"/>`),
    },
    footnotes: {
        segment: "footnotes",
        file: "footnotes.xml",
        xml: FOOTNOTES,
        type: `${WML}.footnotes+xml`,
        doc: docWith(`<w:r><w:footnoteReference w:id="1"/></w:r>`),
    },
    endnotes: {
        segment: "endnotes",
        file: "endnotes.xml",
        xml: ENDNOTES,
        type: `${WML}.endnotes+xml`,
        doc: docWith(`<w:r><w:endnoteReference w:id="1"/></w:r>`),
    },
    comments: {
        segment: "comments",
        file: "comments.xml",
        xml: COMMENTS,
        type: `${WML}.comments+xml`,
        doc: docWith(`<w:r><w:commentReference w:id="0"/></w:r>`),
    },
} as const;
type Used = keyof typeof USED;
const charset = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + CHARSET });
const exact = (k: Used) => mainPart({ ...USED[k] });
const generic = (k: Used) => mainPart({ ...USED[k], type: undefined });

const HEADER = `<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
const STYLES_TYPE = `${WML}.styles+xml`;
const GLOSSARY_STYLES = `<w:styles xmlns:w="${W}"></w:styles>`;
const padded = (k: Used) => mainPart({ ...USED[k], type: USED[k].type + " " });
/** The part related from the main document but not used: no reference, the main document unchanged. */
const unused = (segment: string, file: string, xml: string, type: string) => mainPart({ segment, file, xml, type: type + CHARSET });

const T = (segment: string) => `${WML}.${segment}+xml`;
const HEADER_REF = docWith("", `<w:headerReference w:type="default" r:id="rIdX"/>`);
/** A header the main document references from its sectPr, typed `type`. */
const mainHeader = (type: string) => mainPart({ segment: "header", file: "header9.xml", xml: HEADER, type, doc: HEADER_REF });
/** Session 23's glossary that references footer9.xml from its docPartBody's sectPr. */
const glossaryWithFooterRef = () =>
    `<w:glossaryDocument xmlns:w="${W}" xmlns:r="${REL}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p><w:sectPr><w:footerReference w:type="default" r:id="rIdF"/></w:sectPr></w:docPartBody>` +
    `</w:docPart></w:docParts></w:glossaryDocument>`;
const footerViaGlossary = (type: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossaryWithFooterRef(),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdF" Type="${REL}/footer" Target="footer9.xml"/>`),
        "word/glossary/footer9.xml": FOOTER,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${ov("word/glossary/footer9.xml", type)}`,
        ),
    });

/** S-A: the main document's `w:headerReference r:id="rIdX"` where rIdX is a footer-type relationship to a `w:hdr` part. */
const headerViaFooterRel = (type: string) => mainPart({ segment: "footer", file: "header9.xml", xml: HEADER, type, doc: HEADER_REF });
/** S-B: a footer read through rIdX (footer) that an unused header relationship rIdH also targets. */
const footerAlsoUnusedHeader = (type: string) =>
    buildDocx({
        ...P,
        "word/document.xml": USED.footer.doc,
        "word/footer9.xml": FOOTER,
        "word/_rels/document.xml.rels": rels(
            `<Relationship Id="rIdX" Type="${REL}/footer" Target="footer9.xml"/><Relationship Id="rIdH" Type="${REL}/header" Target="footer9.xml"/>`,
        ),
        "[Content_Types].xml": ct(ov("word/footer9.xml", type)),
    });
/** F3: a reached glossary that references header9.xml from its docPartBody's sectPr. */
const headerViaGlossary = (type: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossaryWithFooterRef().replace(
            `<w:footerReference w:type="default" r:id="rIdF"/>`,
            `<w:headerReference w:type="default" r:id="rIdF"/>`,
        ),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdF" Type="${REL}/header" Target="header9.xml"/>`),
        "word/glossary/header9.xml": HEADER,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${ov("word/glossary/header9.xml", type)}`,
        ),
    });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s26a-control-minimal", "control", () => buildDocx(P)],
    ["headerref-footer-rel-typed-footer-exact", "S-A control", () => headerViaFooterRel(T("footer"))],
    ["headerref-footer-rel-typed-footer-charset", "S-A", () => headerViaFooterRel(T("footer") + CHARSET)],
    ["headerref-footer-rel-typed-header-exact", "S-A", () => headerViaFooterRel(T("header"))],
    ["footer-read-unused-header-rel-typed-header", "S-B", () => footerAlsoUnusedHeader(T("header"))],
    ["footer-read-unused-header-rel-typed-footer", "S-B control", () => footerAlsoUnusedHeader(T("footer"))],
    ["glossary-header-typed-footer-exact", "F3", () => headerViaGlossary(T("footer"))],
    ["s26a-control-minimal-end", "control", () => buildDocx(P)],
];
const only = new Set((process.env.ONLY ?? "").split(",").filter(Boolean));

const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    if (only.size > 0 && !only.has(name)) continue;
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`s26b` was built by a copy with its own header line and this specimens list in place of `s26a`'s:

```ts
// Session 26, chunk s26b (2026-10-24): isolates S-A. Chunk s26a's builder is s26builder.mts.\n// Session 26 (2026-10-24): the items adversarial review AY (layer 128, #602) left for a Word probe.
const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s26b-control-minimal", "control", () => buildDocx(P)],
    ["headerref-header-rel-hdr-typed-header", "control", () => mainHeader(T("header"))],
    [
        "headerref-footer-rel-ftr-typed-footer",
        "S-A reference kind only",
        () => mainPart({ segment: "footer", file: "footer9.xml", xml: FOOTER, type: T("footer"), doc: HEADER_REF }),
    ],
    [
        "footerref-footer-rel-hdr-typed-footer",
        "S-A root only",
        () => mainPart({ segment: "footer", file: "footer9.xml", xml: HEADER, type: T("footer"), doc: USED.footer.doc }),
    ],
    [
        "headerref-header-rel-ftr-typed-header",
        "S-A root only (header side)",
        () => mainPart({ segment: "header", file: "header9.xml", xml: FOOTER, type: T("header"), doc: HEADER_REF }),
    ],
    [
        "headerref-footer-rel-hdr-typed-styles",
        "S-A review AY shape",
        () => mainPart({ segment: "footer", file: "header9.xml", xml: HEADER, type: T("styles"), doc: HEADER_REF }),
    ],
    ["s26b-control-minimal-end", "control", () => buildDocx(P)],
];
```

`s26c` was built the same way, with this header line, two helpers and this specimens list:

```ts
// Session 26, chunk s26c (2026-10-24): #606's unprobed shapes (the mirror, glossary references, an unrelated type).
/** A reached glossary whose docPartBody sectPr carries `ref` (r:id rIdF), rIdF of type `relType` to word/glossary/`file`. */
const glossaryRef = (ref: "headerReference" | "footerReference", relType: string, file: string, xml: string, type: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": glossaryWithFooterRef().replace(
            `<w:footerReference w:type="default" r:id="rIdF"/>`,
            `<w:${ref} w:type="default" r:id="rIdF"/>`,
        ),
        "word/glossary/_rels/document.xml.rels": relsPart(`<Relationship Id="rIdF" Type="${REL}/${relType}" Target="${file}"/>`),
        [`word/glossary/${file}`]: xml,
        "word/_rels/document.xml.rels": rels(`<Relationship Id="rIdG" Type="${REL}/glossaryDocument" Target="glossary/document.xml"/>`),
        "[Content_Types].xml": ct(
            `<Override PartName="/word/glossary/document.xml" ContentType="${GLOSSARY_TYPE}"/>${ov(`word/glossary/${file}`, type)}`,
        ),
    });
/** The main document's body sectPr carries a headerReference naming rId1, MINIMAL_PARTS' styles relationship. */
const headerRefToStyles = () => buildDocx({ ...P, "word/document.xml": docWith("", `<w:headerReference w:type="default" r:id="rId1"/>`) });

const specimens: [string, string, () => Promise<Uint8Array> | Uint8Array][] = [
    ["s26c-control-minimal", "control", () => buildDocx(P)],
    [
        "footerref-header-rel-hdr-typed-header",
        "#606 mirror",
        () => mainPart({ segment: "header", file: "header9.xml", xml: HEADER, type: T("header"), doc: USED.footer.doc }),
    ],
    [
        "footerref-header-rel-ftr-typed-footer",
        "#606 mirror",
        () => mainPart({ segment: "header", file: "footer9.xml", xml: FOOTER, type: T("footer"), doc: USED.footer.doc }),
    ],
    [
        "glossary-headerref-footer-rel-ftr-typed-footer",
        "#606 glossary",
        () => glossaryRef("headerReference", "footer", "footer9.xml", FOOTER, T("footer")),
    ],
    [
        "glossary-footerref-header-rel-hdr-typed-header",
        "#606 glossary mirror",
        () => glossaryRef("footerReference", "header", "header9.xml", HEADER, T("header")),
    ],
    [
        "glossary-footerref-footer-rel-ftr-typed-footer",
        "control",
        () => glossaryRef("footerReference", "footer", "footer9.xml", FOOTER, T("footer")),
    ],
    ["headerref-styles-rel", "#606 unrelated type", () => headerRefToStyles()],
    ["s26c-control-minimal-end", "control", () => buildDocx(P)],
];
```

Session 27's builder (`s27a`–`s27c`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 27 (2026-10-24): the items adversarial review AZ (layer 129, #611) left for a Word probe, plus the
// placements layer 129's check judges without a session 26 observation.
// s27a: S1/S2 — a body headerReference naming a header relationship to a w:hdr part typed header+xml (the clean
//       session 26 shape, `headerref-header-rel-hdr-typed-header`) whose relationship Type is padded with spaces,
//       wrapped in tab/newline character references, upper-cased (`…/HEADER`), `http://example.com/header`, or
//       `…/relationships/custom/header`; S3 — the same clean shape plus a second Relationship with the same Id rIdX,
//       Type footer, listed last.
// s27b: S3 mirror — the session 26 refused shape (headerReference → footer relationship rIdX to a w:ftr part) plus a
//       second rIdX of Type header listed last; the refused shape with its reference moved into a paragraph-level
//       w:pPr/w:sectPr, or into the w:sectPr of a w:sectPrChange (with the clean shape moved there as its control: the
//       schema's CT_SectPrBase has no header reference at all); the clean shape with relationship Type "header" (no URI),
//       or the ISO Strict header relationship URI (http://purl.oclc.org/ooxml/officeDocument/relationships/header).
// s27c: the footer side of s27a/s27b's URI results — a body footerReference naming a footer relationship to a w:ftr part
//       typed footer+xml whose Type is `http://example.com/footer`, `…/relationships/custom/footer`, `…/FOOTER`, or the
//       ISO Strict footer URI, with the unmodified shape as a control.
// Shapes: tests/support/story-content-type-specimens.ts at 9eb10acb (`storyReferenceParts`), as review AZ's probe-az.
// Run from a worktree root at 9eb10acb as a copy: BUILD_DIR=<chunk>/src CHUNK=s27a|s27b|s27c pnpm exec tsx s27builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { STORY_FOOTER_XML, STORY_HEADER_XML, storyContentType, storyReferenceParts } from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const REF = `<w:headerReference w:type="default" r:id="rIdX"/>`;
const clean = (): Parts => storyReferenceParts("headerReference", "header", "header9.xml", STORY_HEADER_XML, storyContentType("header"));
const refused = (): Parts => storyReferenceParts("headerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer"));
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const edit = (parts: Parts, file: string, from: string, to: string): Parts => ({ ...parts, [file]: replaceOnce(parts[file]!, from, to) });
const RELS = "word/_rels/document.xml.rels";
const DOC = "word/document.xml";
const retype = (type: string) => edit(clean(), RELS, `Type="${R}/header"`, `Type="${type}"`);
const control = () => buildDocx(MINIMAL_PARTS);
/** The body sectPr's reference moved into a w:sectPrChange, its last child (CT_SectPr), inside that change's w:sectPr. */
const inSectPrChange = (parts: Parts): Parts =>
    edit(
        edit(parts, DOC, REF, ""),
        DOC,
        "</w:sectPr></w:body>",
        `<w:sectPrChange w:id="1" w:author="A" w:date="2026-10-24T00:00:00Z"><w:sectPr>${REF}</w:sectPr></w:sectPrChange></w:sectPr></w:body>`,
    );

const cleanFooter = (): Parts =>
    storyReferenceParts("footerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer"));
const retypeFooter = (type: string) => edit(cleanFooter(), RELS, `Type="${R}/footer"`, `Type="${type}"`);

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s27a: [
        ["s27a-control-minimal", "control", control],
        ["headerref-header-rel-type-padded", "AZ S1", () => buildDocx(retype(` ${R}/header `))],
        ["headerref-header-rel-type-tab-newline", "AZ S1", () => buildDocx(retype(`&#x9;${R}/header&#xA;`))],
        ["headerref-header-rel-type-upper", "AZ S2", () => buildDocx(retype(`${R}/HEADER`))],
        ["headerref-header-rel-type-example-com", "AZ S2", () => buildDocx(retype("http://example.com/header"))],
        ["headerref-header-rel-type-custom-header", "AZ S2", () => buildDocx(retype(`${R}/custom/header`))],
        [
            "headerref-duplicate-id-last-footer",
            "AZ S3",
            () =>
                buildDocx(
                    edit(
                        clean(),
                        RELS,
                        "</Relationships>",
                        `<Relationship Id="rIdX" Type="${R}/footer" Target="header9.xml"/></Relationships>`,
                    ),
                ),
        ],
        ["s27a-control-minimal-end", "control", control],
    ],
    s27b: [
        ["s27b-control-minimal", "control", control],
        [
            "headerref-duplicate-id-last-header",
            "AZ S3 mirror",
            () =>
                buildDocx(
                    edit(
                        refused(),
                        RELS,
                        "</Relationships>",
                        `<Relationship Id="rIdX" Type="${R}/header" Target="footer9.xml"/></Relationships>`,
                    ),
                ),
        ],
        [
            "headerref-footer-rel-paragraph-sectpr",
            "placement",
            () => {
                const p = edit(refused(), DOC, REF, "");
                return buildDocx(edit(p, DOC, "<w:r>", `<w:pPr><w:sectPr>${REF}</w:sectPr></w:pPr><w:r>`));
            },
        ],
        ["headerref-footer-rel-in-sectprchange", "placement", () => buildDocx(inSectPrChange(refused()))],
        ["headerref-header-rel-in-sectprchange", "placement control", () => buildDocx(inSectPrChange(clean()))],
        ["headerref-header-rel-type-bare", "AZ S2", () => buildDocx(retype("header"))],
        [
            "headerref-header-rel-type-strict-uri",
            "AZ S2",
            () => buildDocx(retype("http://purl.oclc.org/ooxml/officeDocument/relationships/header")),
        ],
        ["s27b-control-minimal-end", "control", control],
    ],
    s27c: [
        ["s27c-control-minimal", "control", control],
        ["footerref-footer-rel-type-example-com", "AZ S2 footer", () => buildDocx(retypeFooter("http://example.com/footer"))],
        ["footerref-footer-rel-type-custom-footer", "AZ S2 footer", () => buildDocx(retypeFooter(`${R}/custom/footer`))],
        ["footerref-footer-rel-type-upper", "AZ S2 footer", () => buildDocx(retypeFooter(`${R}/FOOTER`))],
        [
            "footerref-footer-rel-type-strict-uri",
            "AZ S2 footer",
            () => buildDocx(retypeFooter("http://purl.oclc.org/ooxml/officeDocument/relationships/footer")),
        ],
        ["footerref-footer-rel-ftr-typed-footer", "control (session 26 clean footer shape)", () => buildDocx(cleanFooter())],
        ["s27c-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

Session 28's builder (`s28a`) is another standalone script, run the same way:

```ts
// Session 28 (2026-10-24): does Word read a w:hyperlink's relationship Type exactly, as session 27 found for header and
// footer references (#613)? `word-hyperlink-relationship` (src/scripts/office/checks/word-hyperlink.ts) accepts any
// Type that ends in /hyperlink with TargetMode External.
// s28a: `MINIMAL_PARTS` with a body w:hyperlink r:id="rIdH" naming an External relationship to https://example.org/
//       whose Type is the Transitional hyperlink URI (control), the ISO Strict hyperlink URI,
//       `http://example.com/hyperlink`, `…/relationships/custom/hyperlink`, or `…/relationships/HYPERLINK`.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s28a pnpm exec tsx s28builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const RELS = "word/_rels/document.xml.rels";
const DOC = "word/document.xml";
const hyperlink = (type: string): Parts => {
    const parts: Parts = { ...(MINIMAL_PARTS as Parts) };
    parts[DOC] = replaceOnce(
        replaceOnce(parts[DOC]!, "<w:document ", `<w:document xmlns:r="${R}" `),
        "<w:r><w:t>Hello</w:t></w:r>",
        `<w:r><w:t>Hello</w:t></w:r><w:hyperlink r:id="rIdH"><w:r><w:t>link</w:t></w:r></w:hyperlink>`,
    );
    parts[RELS] = replaceOnce(
        parts[RELS]!,
        "</Relationships>",
        `<Relationship Id="rIdH" Type="${type}" Target="https://example.org/" TargetMode="External"/></Relationships>`,
    );
    return parts;
};
const control = () => buildDocx(MINIMAL_PARTS);

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s28a: [
        ["s28a-control-minimal", "control", control],
        ["hyperlink-rel-type-transitional", "control", () => buildDocx(hyperlink(`${R}/hyperlink`))],
        [
            "hyperlink-rel-type-strict-uri",
            "#613 class",
            () => buildDocx(hyperlink("http://purl.oclc.org/ooxml/officeDocument/relationships/hyperlink")),
        ],
        ["hyperlink-rel-type-example-com", "#613 class", () => buildDocx(hyperlink("http://example.com/hyperlink"))],
        ["hyperlink-rel-type-custom-hyperlink", "#613 class", () => buildDocx(hyperlink(`${R}/custom/hyperlink`))],
        ["hyperlink-rel-type-upper", "#613 class", () => buildDocx(hyperlink(`${R}/HYPERLINK`))],
        ["s28a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 29's builder (`s29a`, `s29b`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 29 (2026-10-24): duplicate relationship Ids without a content-type confound. Session 27's duplicate-Id
// specimens each had one entry whose target's content type disagreed with that entry's relationship type, so they
// cannot tell a duplicate Id from a type/content mismatch. CodeRabbit's review of #611 (comment 4368831374) asked about
// a header reference whose Id names a footer relationship first and a header relationship last.
// s29a: the clean session 26 shape (body w:headerReference r:id="rIdX" → header relationship → `header9.xml`, a w:hdr
//       typed header+xml) plus a correctly typed `footer9.xml` (w:ftr, footer+xml) and, under the same Id rIdX:
//       a footer relationship to footer9.xml listed first (header last); listed last (header first); a second header
//       relationship to header9.xml (same type, same target); and, with no second rIdX, two unreferenced External
//       hyperlink relationships sharing the Id rIdZ.
// s29b: review BA's S1 — the Transitional header, footer and hyperlink Types spelled with `https:` (session 26's clean
//       shapes and session 28's hyperlink shape otherwise) — and two unreferenced External hyperlink relationships
//       sharing the Id rIdZ in the package `_rels/.rels`, or in the header part's own `word/_rels/header9.xml.rels`.
// Shapes: tests/support/story-content-type-specimens.ts (`storyReferenceParts`).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s29a|s29b pnpm exec tsx s29builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { STORY_FOOTER_XML, STORY_HEADER_XML, storyContentType, storyReferenceParts } from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const RELS = "word/_rels/document.xml.rels";
const CT = "[Content_Types].xml";
const HEADER_REL = `<Relationship Id="rIdX" Type="${R}/header" Target="header9.xml"/>`;
const FOOTER_REL = `<Relationship Id="rIdX" Type="${R}/footer" Target="footer9.xml"/>`;
/** The clean shape plus a correctly typed footer9.xml; `rels` replaces the header relationship. */
const withFooterPart = (rels: string): Parts => {
    const parts: Parts = {
        ...storyReferenceParts("headerReference", "header", "header9.xml", STORY_HEADER_XML, storyContentType("header")),
    };
    parts["word/footer9.xml"] = STORY_FOOTER_XML;
    parts[CT] = replaceOnce(
        parts[CT]!,
        "</Types>",
        `<Override PartName="/word/footer9.xml" ContentType="${storyContentType("footer")}"/></Types>`,
    );
    parts[RELS] = replaceOnce(parts[RELS]!, HEADER_REL, rels);
    return parts;
};
const control = () => buildDocx(MINIMAL_PARTS);
const clean = (): Parts => ({
    ...storyReferenceParts("headerReference", "header", "header9.xml", STORY_HEADER_XML, storyContentType("header")),
});
const edit = (parts: Parts, file: string, from: string, to: string): Parts => ({ ...parts, [file]: replaceOnce(parts[file]!, from, to) });
const retype = (parts: Parts, from: string, to: string): Parts => edit(parts, RELS, `Type="${from}"`, `Type="${to}"`);
/** Two unreferenced External hyperlink relationships sharing the Id rIdZ. */
const DUP_Z =
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://a.example/" TargetMode="External"/>` +
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://b.example/" TargetMode="External"/>`;
/** Session 28's shape: MINIMAL_PARTS plus a body w:hyperlink r:id="rIdH" naming an External relationship of `type`. */
const hyperlink = (type: string): Parts => {
    const parts: Parts = { ...(MINIMAL_PARTS as Parts) };
    parts["word/document.xml"] = replaceOnce(
        replaceOnce(parts["word/document.xml"]!, "<w:document ", `<w:document xmlns:r="${R}" `),
        "<w:r><w:t>Hello</w:t></w:r>",
        `<w:r><w:t>Hello</w:t></w:r><w:hyperlink r:id="rIdH"><w:r><w:t>link</w:t></w:r></w:hyperlink>`,
    );
    return edit(
        parts,
        RELS,
        "</Relationships>",
        `<Relationship Id="rIdH" Type="${type}" Target="https://example.org/" TargetMode="External"/></Relationships>`,
    );
};

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s29a: [
        ["s29a-control-minimal", "control", control],
        ["headerref-dup-id-footer-first-header-last", "CR 4368831374", () => buildDocx(withFooterPart(FOOTER_REL + HEADER_REL))],
        ["headerref-dup-id-header-first-footer-last", "CR 4368831374 mirror", () => buildDocx(withFooterPart(HEADER_REL + FOOTER_REL))],
        ["headerref-dup-id-header-twice", "duplicate, same type and target", () => buildDocx(withFooterPart(HEADER_REL + HEADER_REL))],
        [
            "dup-id-unreferenced-hyperlinks",
            "duplicate, unreferenced",
            () =>
                buildDocx(
                    withFooterPart(
                        HEADER_REL +
                            `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://a.example/" TargetMode="External"/>` +
                            `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://b.example/" TargetMode="External"/>`,
                    ),
                ),
        ],
        [
            "headerref-header-rel-with-footer-part",
            "control (clean shape plus the unreferenced footer9.xml)",
            () => buildDocx(withFooterPart(HEADER_REL)),
        ],
        ["s29a-control-minimal-end", "control", control],
    ],
    s29b: [
        ["s29b-control-minimal", "control", control],
        [
            "headerref-header-rel-type-https",
            "review BA S1",
            () => buildDocx(retype(clean(), `${R}/header`, `${R.replace("http:", "https:")}/header`)),
        ],
        [
            "footerref-footer-rel-type-https",
            "review BA S1",
            () =>
                buildDocx(
                    retype(
                        storyReferenceParts("footerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer")),
                        `${R}/footer`,
                        `${R.replace("http:", "https:")}/footer`,
                    ),
                ),
        ],
        ["hyperlink-rel-type-https", "review BA S1", () => buildDocx(hyperlink(`${R.replace("http:", "https:")}/hyperlink`))],
        [
            "dup-id-package-rels-unreferenced-hyperlinks",
            "duplicate, package .rels",
            () => buildDocx(edit(clean(), "_rels/.rels", "</Relationships>", DUP_Z + "</Relationships>")),
        ],
        [
            "dup-id-header-part-rels-unreferenced-hyperlinks",
            "duplicate, header part .rels",
            () =>
                buildDocx({
                    ...clean(),
                    "word/_rels/header9.xml.rels": `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${DUP_Z}</Relationships>`,
                }),
        ],
        ["s29b-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 30's builder (`s30a`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 30 (2026-10-24): adversarial review BB's suspected items on #615 (layer 129, #611). Session 29 found Word
// refusing duplicate relationship Ids in the package and main-document .rels, and opening a header part's own .rels
// with duplicates clean. Unobserved: a reached glossary's own .rels (S1), a word/_rels/document.xml.rels that belongs
// to no main document (S2), and a relocated main document's own .rels (the validator extends the rule to it).
// s30a: session 26's clean glossary footer shape (`glossaryStoryReferenceParts`) as a control, and with two
//       unreferenced External hyperlink relationships sharing rIdZ in `word/glossary/_rels/document.xml.rels`;
//       the main document moved to `word/main.xml` (package relationship and Override retargeted) alone (control),
//       with an orphan
//       `word/document.xml` and `word/_rels/document.xml.rels`, without (control) and with the rIdZ pair in that
//       orphan sidecar; and the moved main document with the rIdZ pair in its own `word/_rels/main.xml.rels`.
// Shapes: tests/support/story-content-type-specimens.ts and tests/relationship-ids.integration.test.ts (`relocated`).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s30a pnpm exec tsx s30builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { STORY_FOOTER_XML, glossaryStoryReferenceParts, storyContentType } from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const MAIN = "word/document.xml";
const RELS = "word/_rels/document.xml.rels";
const CT = "[Content_Types].xml";
const PACKAGE_RELS = "_rels/.rels";
/** Two unreferenced External hyperlink relationships sharing the Id rIdZ. */
const DUP_Z =
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://a.example/" TargetMode="External"/>` +
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://b.example/" TargetMode="External"/>`;
const withDup = (parts: Parts, rels: string): Parts => ({
    ...parts,
    [rels]: replaceOnce(parts[rels]!, "</Relationships>", `${DUP_Z}</Relationships>`),
});
const glossary = (): Parts => ({
    ...glossaryStoryReferenceParts("footerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer")),
});
/** The main document moved to word/main.xml; with `orphan`, an unreached word/document.xml and its sidecar stay behind. */
const relocated = (orphan: boolean): Parts => {
    const parts: Parts = { ...(MINIMAL_PARTS as Parts) };
    parts["word/main.xml"] = parts[MAIN]!;
    parts["word/_rels/main.xml.rels"] = parts[RELS]!;
    delete parts[MAIN];
    delete parts[RELS];
    parts[CT] = replaceOnce(parts[CT]!, "/word/document.xml", "/word/main.xml");
    parts[PACKAGE_RELS] = replaceOnce(parts[PACKAGE_RELS]!, "word/document.xml", "word/main.xml");
    if (orphan) {
        parts[MAIN] = MINIMAL_PARTS[MAIN]!;
        parts[RELS] = MINIMAL_PARTS[RELS]!;
    }
    return parts;
};
const control = () => buildDocx(MINIMAL_PARTS);

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s30a: [
        ["s30a-control-minimal", "control", control],
        ["glossary-footerref-footer-rel-ftr-typed-footer", "control (session 26 clean glossary footer)", () => buildDocx(glossary())],
        ["dup-id-glossary-sidecar", "review BB S1", () => buildDocx(withDup(glossary(), "word/glossary/_rels/document.xml.rels"))],
        ["relocated-main-transitional", "control (main document moved to word/main.xml)", () => buildDocx(relocated(false))],
        ["relocated-main-orphan-sidecar", "control (review BB S2 shape, no duplicate)", () => buildDocx(relocated(true))],
        ["dup-id-non-main-document-sidecar", "review BB S2", () => buildDocx(withDup(relocated(true), RELS))],
        ["dup-id-relocated-main-transitional", "#615 extension", () => buildDocx(withDup(relocated(false), "word/_rels/main.xml.rels"))],
        ["s30a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 31's builder (`s31a`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 31 (2026-10-25): adversarial review BC's suspected item on #617 (layer 129, #611). The duplicate relationship
// Id walk (validateAllRelationshipIds) visits only the .rels of owners whose names end in .xml, so a story root stored
// under another extension carries duplicate Ids no profile reports as rels-id-duplicate. Session 16 observed a correctly
// typed main document stored as word/document.bin open clean; nobody has observed duplicate Ids beside such a root.
// s31a: MINIMAL_PARTS with the main document renamed word/document.bin (package relationship, Override and sidecar
//       renamed with it), without (control) and with two unreferenced External hyperlink relationships sharing rIdZ in
//       word/_rels/document.bin.rels; session 26's clean glossary footer shape with the glossary renamed
//       word/glossary/document.bin (main-document relationship, Override and sidecar renamed with it), without
//       (control) and with the rIdZ pair in word/glossary/_rels/document.bin.rels.
// Shapes: tests/support/story-content-type-specimens.ts and review BC's suffix-bc.tmp.mts.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s31a pnpm exec tsx s31builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { STORY_FOOTER_XML, glossaryStoryReferenceParts, storyContentType } from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const CT = "[Content_Types].xml";
/** Two unreferenced External hyperlink relationships sharing the Id rIdZ. */
const DUP_Z =
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://a.example/" TargetMode="External"/>` +
    `<Relationship Id="rIdZ" Type="${R}/hyperlink" Target="https://b.example/" TargetMode="External"/>`;
const withDup = (parts: Parts, rels: string): Parts => ({
    ...parts,
    [rels]: replaceOnce(parts[rels]!, "</Relationships>", `${DUP_Z}</Relationships>`),
});
/** Rename a story root `<dir>/document.xml` to `<dir>/document.bin`, with its sidecar, Override and the relationship naming it. */
const toBin = (parts: Parts, dir: string, owner: string, target: string): Parts => {
    const out: Parts = { ...parts };
    out[`${dir}/document.bin`] = out[`${dir}/document.xml`]!;
    out[`${dir}/_rels/document.bin.rels`] = out[`${dir}/_rels/document.xml.rels`]!;
    delete out[`${dir}/document.xml`];
    delete out[`${dir}/_rels/document.xml.rels`];
    out[CT] = replaceOnce(out[CT]!, `PartName="/${dir}/document.xml"`, `PartName="/${dir}/document.bin"`);
    out[owner] = replaceOnce(out[owner]!, `Target="${target}"`, `Target="${target.replace(/xml$/, "bin")}"`);
    return out;
};
const binMain = (): Parts => toBin(MINIMAL_PARTS as Parts, "word", "_rels/.rels", "word/document.xml");
const binGlossary = (): Parts =>
    toBin(
        glossaryStoryReferenceParts("footerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer")),
        "word/glossary",
        "word/_rels/document.xml.rels",
        "glossary/document.xml",
    );
const control = () => buildDocx(MINIMAL_PARTS);

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s31a: [
        ["s31a-control-minimal", "control", control],
        ["bin-main", "control (main document stored as word/document.bin)", () => buildDocx(binMain())],
        ["dup-id-bin-main-sidecar", "review BC S1", () => buildDocx(withDup(binMain(), "word/_rels/document.bin.rels"))],
        ["bin-glossary", "control (glossary stored as word/glossary/document.bin)", () => buildDocx(binGlossary())],
        ["dup-id-bin-glossary-sidecar", "review BC S1", () => buildDocx(withDup(binGlossary(), "word/glossary/_rels/document.bin.rels"))],
        ["s31a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 32's builder (`s32a`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 32 (2026-10-25): adversarial review BD's suspected items on #618 (layer 129, #611). Every XML check is gated on
// a part name ending in .xml, so a main document stored as word/document.bin is never parsed: a malformed one, or one
// whose r:id names no relationship, passes every profile. Session 31 showed Word reads such a main document's sidecar.
// s32a: MINIMAL_PARTS with the main document truncated (its closing `</w:body></w:document>` removed), stored as
//       word/document.xml (calibration) and as word/document.bin (package relationship, Override and sidecar renamed);
//       the main document's sectPr given a `w:footerReference w:type="default" r:id="rId9"` (xmlns:r declared), with its
//       .rels removed, or kept without an rId9, each stored as .xml (calibration) and as .bin.
// Shapes: tests/support/minimal-docx.ts and review BD's report.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s32a pnpm exec tsx s32builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const RELS = "word/_rels/document.xml.rels";
/** Rename the main document to word/document.bin, with its sidecar (when present), Override and package relationship. */
const toBin = (parts: Parts): Parts => {
    const out: Parts = { ...parts };
    out["word/document.bin"] = out[MAIN]!;
    delete out[MAIN];
    if (out[RELS] !== undefined) {
        out["word/_rels/document.bin.rels"] = out[RELS]!;
        delete out[RELS];
    }
    out[CT] = replaceOnce(out[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/document.bin"');
    out["_rels/.rels"] = replaceOnce(out["_rels/.rels"]!, 'Target="word/document.xml"', 'Target="word/document.bin"');
    return out;
};
const truncated = (): Parts => ({ ...(MINIMAL_PARTS as Parts), [MAIN]: replaceOnce(MINIMAL_PARTS[MAIN]!, "</w:body></w:document>", "") });
/** The main document's sectPr references footer rId9; `sidecar: false` removes its .rels, otherwise the .rels has no rId9. */
const footerRef = (sidecar: boolean): Parts => {
    const parts: Parts = { ...(MINIMAL_PARTS as Parts) };
    parts[MAIN] = replaceOnce(
        replaceOnce(parts[MAIN]!, "<w:document ", `<w:document xmlns:r="${R}" `),
        "<w:sectPr>",
        '<w:sectPr><w:footerReference w:type="default" r:id="rId9"/>',
    );
    if (!sidecar) delete parts[RELS];
    return parts;
};
const control = () => buildDocx(MINIMAL_PARTS);

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s32a: [
        ["s32a-control-minimal", "control", control],
        ["main-truncated", "calibration (.xml twin of review BD S1)", () => buildDocx(truncated())],
        ["bin-main-truncated", "review BD S1", () => buildDocx(toBin(truncated()))],
        ["footerref-rid-no-sidecar", "calibration (.xml twin of review BD S2)", () => buildDocx(footerRef(false))],
        ["bin-footerref-rid-no-sidecar", "review BD S2", () => buildDocx(toBin(footerRef(false)))],
        ["footerref-rid-missing", "calibration (.xml twin of review BD S2)", () => buildDocx(footerRef(true))],
        ["bin-footerref-rid-missing", "review BD S2", () => buildDocx(toBin(footerRef(true)))],
        ["s32a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 33's builder (`s33a`–`s33e`) is another standalone script, run the same way, with `CHUNK` naming the chunk:

```ts
// Session 33 (2026-10-25): adversarial review BE's suspected items on #619 (layer 129, #611), filed as #623, #624, #625.
// s33a: #623, an empty r:id on a story reference (and a reference with no r:id at all); #624, a dangling footer
//       reference in the ISO Strict WordprocessingML and relationships namespaces with the main document's .rels
//       removed, with a clean control of that namespace shape and a calibration that keeps the .rels.
// s33b: #625, a main document or reached glossary stored as word/header1.xml with a dangling footer reference and no
//       .rels, each with a clean control of the renamed shape, plus the ordinary reached glossary with no .rels as
//       calibration.
// s33c: re-probes of s33a's three inconclusive items; #624's isolation control (ISO Strict namespaces, no .rels and no
//       reference); #631, review BG's S-B: a Transitional footer reference whose only id is an ISO Strict rs:id, dangling
//       and naming a valid footer relationship (the PDF's "Footer" text tells whether Word read the attribute).
// s33d: #632, review BG's S-A (the footer relationship inside mc:AlternateContent's Fallback in the .rels) and S-C (the
//       id in a third namespace, dangling and naming a valid footer relationship), with session 26's clean footer as
//       calibration.
// s33e: what #632's fix and #623's header mirror would otherwise assume: a header reference with no r:id; the
//       officeDocument relationship in mc:Fallback of _rels/.rels; the footer relationship in an mc:Choice Word
//       understands (w14), Fallback empty; a foreign child of the document's .rels declared mc:Ignorable; and an
//       mc:Fallback that yields a foreign element beside the footer relationship.
// Shapes: tests/support/minimal-docx.ts, tests/support/story-content-type-specimens.ts and reviews BE and BG.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s33a pnpm exec tsx s33builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import {
    STORY_FOOTER_XML,
    glossaryStoryReferenceParts,
    storyContentType,
    storyReferenceParts,
} from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W_STRICT = "http://purl.oclc.org/ooxml/wordprocessingml/main";
const R_STRICT = "http://purl.oclc.org/ooxml/officeDocument/relationships";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const RELS = "word/_rels/document.xml.rels";
const STYLES = "word/styles.xml";

/** The main document's body sectPr gets `reference` (with `attrs`); `r` is the relationships namespace declared. */
const withReference = (parts: Parts, reference: string, r = R): Parts => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(parts[MAIN]!, "<w:document ", `<w:document xmlns:r="${r}" `), "<w:sectPr>", `<w:sectPr>${reference}`),
});
/** Review BE S2: the main document and styles in the ISO Strict WordprocessingML namespace. */
const strictNamespace = (parts: Parts): Parts => ({
    ...parts,
    [MAIN]: parts[MAIN]!.split(W).join(W_STRICT),
    [STYLES]: parts[STYLES]!.split(W).join(W_STRICT),
});
const withoutRels = (parts: Parts, rels = RELS): Parts => {
    const out = { ...parts };
    if (out[rels] === undefined) throw new Error(`missing ${rels}`);
    delete out[rels];
    return out;
};
/** Review BE S2: the main document stored as word/header1.xml, with its .rels, Override and package relationship. */
const mainAsHeader1 = (parts: Parts): Parts => {
    const out: Parts = { ...parts };
    out["word/header1.xml"] = out[MAIN]!;
    delete out[MAIN];
    if (out[RELS] !== undefined) {
        out["word/_rels/header1.xml.rels"] = out[RELS]!;
        delete out[RELS];
    }
    out[CT] = replaceOnce(out[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/header1.xml"');
    out["_rels/.rels"] = replaceOnce(out["_rels/.rels"]!, 'Target="word/document.xml"', 'Target="word/header1.xml"');
    return out;
};
/** Session 26's clean reached-glossary footer shape. */
const glossary = (): Parts =>
    glossaryStoryReferenceParts("footerReference", "footer", "footer9.xml", STORY_FOOTER_XML, storyContentType("footer"));
const G = "word/glossary/document.xml";
const GRELS = "word/glossary/_rels/document.xml.rels";
/** Review BE S2: the reached glossary stored as word/header1.xml, with its .rels (Target adjusted), Override and relationship. */
const glossaryAsHeader1 = (parts: Parts): Parts => {
    const out: Parts = { ...parts };
    out["word/header1.xml"] = out[G]!;
    delete out[G];
    if (out[GRELS] !== undefined) {
        out["word/_rels/header1.xml.rels"] = replaceOnce(out[GRELS]!, 'Target="footer9.xml"', 'Target="glossary/footer9.xml"');
        delete out[GRELS];
    }
    out[CT] = replaceOnce(out[CT]!, 'PartName="/word/glossary/document.xml"', 'PartName="/word/header1.xml"');
    out[RELS] = replaceOnce(out[RELS]!, 'Target="glossary/document.xml"', 'Target="header1.xml"');
    return out;
};
const FOOTER_RID9 = '<w:footerReference w:type="default" r:id="rId9"/>';
const control = () => buildDocx(MINIMAL_PARTS);
/** Session 26's clean main-document footer: the body sectPr's footerReference r:id="rIdX" names a footer relationship to word/footer1.xml. */
const validFooter = (): Parts =>
    storyReferenceParts("footerReference", "footer", "footer1.xml", STORY_FOOTER_XML, storyContentType("footer"));
/** The main document's reference id moved to attribute `qname`, with `xmlns:${prefix}` bound to `uri` on w:document. */
const idIn = (parts: Parts, from: string, qname: string, prefix: string, uri: string): Parts => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(parts[MAIN]!, "<w:document ", `<w:document xmlns:${prefix}="${uri}" `), from, qname),
});
/** Review BG S-A: the footer relationship moved into an mc:AlternateContent whose Choice requires a namespace Word does not understand. */
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const footerRelInFallback = (parts: Parts): Parts => {
    const rel = /<Relationship Id="rIdX"[^>]*\/>/.exec(parts[RELS]!)?.[0];
    if (!rel) throw new Error("missing rIdX relationship");
    const rels = replaceOnce(
        replaceOnce(
            parts[RELS]!,
            rel,
            `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>${rel}</mc:Fallback></mc:AlternateContent>`,
        ),
        '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"',
        `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships" xmlns:mc="${MC}" xmlns:foo="urn:foo"`,
    );
    return { ...parts, [RELS]: rels };
};
const PR = '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"';
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
/** The Relationship matched by `id` in `relsPart`, replaced by `wrap(rel)`, with `decls` added to the Relationships root. */
const wrapRelationship = (parts: Parts, relsPart: string, id: string, wrap: (rel: string) => string, decls: string): Parts => {
    const rel = new RegExp(`<Relationship Id="${id}"[^>]*/>`).exec(parts[relsPart]!)?.[0];
    if (!rel) throw new Error(`missing ${id} in ${relsPart}`);
    return { ...parts, [relsPart]: replaceOnce(replaceOnce(parts[relsPart]!, rel, wrap(rel)), PR, `${PR} ${decls}`) };
};

const chunks: Record<string, [string, string, () => Promise<Uint8Array> | Uint8Array][]> = {
    s33a: [
        ["s33a-control-minimal", "control", control],
        [
            "footerref-rid-empty",
            "#623",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:footerReference w:type="default" r:id=""/>')),
        ],
        [
            "headerref-rid-empty",
            "#623",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:headerReference w:type="default" r:id=""/>')),
        ],
        [
            "footerref-no-rid",
            "#623 (no r:id at all)",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:footerReference w:type="default"/>')),
        ],
        [
            "strict-ns-control",
            "#624 control (ISO Strict namespaces, no reference)",
            () => buildDocx(strictNamespace(MINIMAL_PARTS as Parts)),
        ],
        [
            "strict-ns-footerref-no-sidecar",
            "#624",
            () => buildDocx(withoutRels(withReference(strictNamespace(MINIMAL_PARTS as Parts), FOOTER_RID9, R_STRICT))),
        ],
        [
            "strict-ns-footerref-rid-missing",
            "#624 calibration (.rels kept)",
            () => buildDocx(withReference(strictNamespace(MINIMAL_PARTS as Parts), FOOTER_RID9, R_STRICT)),
        ],
        ["s33a-control-minimal-end", "control", control],
    ],
    s33b: [
        ["s33b-control-minimal", "control", control],
        [
            "header1-main-control",
            "#625 control (main document as word/header1.xml)",
            () => buildDocx(mainAsHeader1(MINIMAL_PARTS as Parts)),
        ],
        [
            "header1-main-footerref-no-sidecar",
            "#625",
            () => buildDocx(withoutRels(mainAsHeader1(withReference(MINIMAL_PARTS as Parts, FOOTER_RID9)), "word/_rels/header1.xml.rels")),
        ],
        ["header1-glossary-control", "#625 control (glossary as word/header1.xml)", () => buildDocx(glossaryAsHeader1(glossary()))],
        [
            "header1-glossary-footerref-no-sidecar",
            "#625",
            () => buildDocx(withoutRels(glossaryAsHeader1(glossary()), "word/_rels/header1.xml.rels")),
        ],
        [
            "glossary-footerref-no-sidecar",
            "#625 calibration (ordinary glossary, no .rels)",
            () => buildDocx(withoutRels(glossary(), GRELS)),
        ],
        ["s33b-control-minimal-end", "control", control],
    ],
    s33c: [
        ["s33c-control-minimal", "control", control],
        [
            "footerref-no-rid",
            "#623/#631/#632 (re-probe of s33a: no r:id at all)",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:footerReference w:type="default"/>')),
        ],
        [
            "footerref-rid-empty",
            "#623 (re-probe of s33a)",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:footerReference w:type="default" r:id=""/>')),
        ],
        [
            "strict-ns-footerref-rid-missing",
            "#624 calibration (re-probe of s33a, .rels kept)",
            () => buildDocx(withReference(strictNamespace(MINIMAL_PARTS as Parts), FOOTER_RID9, R_STRICT)),
        ],
        [
            "strict-ns-no-rels-no-reference",
            "#624 isolation (ISO Strict namespaces, no .rels, no reference)",
            () => buildDocx(withoutRels(strictNamespace(MINIMAL_PARTS as Parts))),
        ],
        [
            "rs-id-dangling",
            "#631 (Transitional reference, only rs:id, names no Relationship)",
            () =>
                buildDocx(
                    idIn(
                        MINIMAL_PARTS as Parts,
                        "<w:sectPr>",
                        '<w:sectPr><w:footerReference w:type="default" rs:id="rId9"/>',
                        "rs",
                        R_STRICT,
                    ),
                ),
        ],
        [
            "rs-id-valid-footer",
            "#631 twin (only rs:id, names the footer relationship)",
            () => buildDocx(idIn(validFooter(), ' r:id="rIdX"', ' rs:id="rIdX"', "rs", R_STRICT)),
        ],
        ["s33c-control-minimal-end", "control", control],
    ],
    s33d: [
        ["s33d-control-minimal", "control", control],
        ["footer-valid-calibration", "#631/#632 calibration (session 26's clean footer)", () => buildDocx(validFooter())],
        [
            "mce-rels-fallback-footer",
            "#632 S-A (footer relationship in mc:Fallback of the .rels)",
            () => buildDocx(footerRelInFallback(validFooter())),
        ],
        [
            "third-ns-id-dangling",
            "#632 S-C (only x:id in urn:x, names no Relationship)",
            () =>
                buildDocx(
                    idIn(MINIMAL_PARTS as Parts, "<w:sectPr>", '<w:sectPr><w:footerReference w:type="default" x:id="rId9"/>', "x", "urn:x"),
                ),
        ],
        [
            "third-ns-id-valid-footer",
            "#632 S-C twin (only x:id, names the footer relationship)",
            () => buildDocx(idIn(validFooter(), ' r:id="rIdX"', ' x:id="rIdX"', "x", "urn:x")),
        ],
        ["s33d-control-minimal-end", "control", control],
    ],
    s33e: [
        ["s33e-control-minimal", "control", control],
        [
            "headerref-no-rid",
            "#623 header mirror (no r:id at all)",
            () => buildDocx(withReference(MINIMAL_PARTS as Parts, '<w:headerReference w:type="default"/>')),
        ],
        [
            "mce-package-rels-fallback-main",
            "#632 (officeDocument relationship in mc:Fallback of _rels/.rels)",
            () =>
                buildDocx(
                    wrapRelationship(
                        MINIMAL_PARTS as Parts,
                        "_rels/.rels",
                        "rId1",
                        (rel) => `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>${rel}</mc:Fallback></mc:AlternateContent>`,
                        `xmlns:mc="${MC}" xmlns:foo="urn:foo"`,
                    ),
                ),
        ],
        [
            "mce-rels-choice-w14-footer",
            "#632 (footer relationship in an understood mc:Choice, empty Fallback)",
            () =>
                buildDocx(
                    wrapRelationship(
                        validFooter(),
                        RELS,
                        "rIdX",
                        (rel) => `<mc:AlternateContent><mc:Choice Requires="w14">${rel}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                        `xmlns:mc="${MC}" xmlns:w14="${W14}"`,
                    ),
                ),
        ],
        [
            "mce-rels-ignorable-foreign",
            "#632 (foreign child of the document's .rels, its prefix mc:Ignorable)",
            () =>
                buildDocx(
                    wrapRelationship(
                        validFooter(),
                        RELS,
                        "rIdX",
                        (rel) => `${rel}<x:Wrap/>`,
                        `xmlns:mc="${MC}" xmlns:x="urn:x" mc:Ignorable="x"`,
                    ),
                ),
        ],
        [
            "mce-rels-fallback-foreign",
            "#632 (mc:Fallback yields a foreign element beside the footer relationship)",
            () =>
                buildDocx(
                    wrapRelationship(
                        validFooter(),
                        RELS,
                        "rIdX",
                        (rel) =>
                            `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>${rel}<x:Wrap/></mc:Fallback></mc:AlternateContent>`,
                        `xmlns:mc="${MC}" xmlns:foo="urn:foo" xmlns:x="urn:x"`,
                    ),
                ),
        ],
        ["s33e-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 34's builder (`s34a`–`s34d`) is another standalone script, run the same way from the layer 131 worktree, with `CHUNK` naming the chunk:

```ts
// Session 34 (2026-10-25): adversarial review of #632's fix (45abe57e, layer 131) by empryo devin/swe-2, findings 1, 2
// and 4. Before that fix a raw mc:AlternateContent child of a .rels part was a blocking opc-relationships-structure
// error; after it, readers that still read the stored .rels (word-read-parts' relationshipsOf/packageReach,
// properties-parts, validateAllRelationshipIds) miss a relationship that markup compatibility selects, so a defect
// reached only through it is demoted under word-valid. Each wrapped specimen moves one relationship into
// <mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>…</mc:Fallback></mc:AlternateContent> (Word follows it:
// s33d/s33e) and carries a defect Word refuses when the relationship is direct; its direct twin runs beside it.
// s34a: C, a malformed main document reached through the Fallback officeDocument relationship; D, a zero-byte
//       word/_rels/document.xml.rels beside that main document; E, _rels/.rels holding a direct rId1 (officeDocument)
//       and a Fallback rId1 (styles), a duplicate Id only in the processed view; each with its direct twin.
// s34b: F, a malformed docProps/core.xml reached through a Fallback core-properties relationship; H, session 26's
//       footer typed as a header (#600) with its relationship in the Fallback; each with its direct twin; I,
//       mc:MustUnderstand="foo" on the _rels/.rels root (review finding 4); L, the footer relationship in an mc:Choice
//       whose Requires prefix is undeclared, Fallback empty (an mce-malformed AlternateContent; review finding 4).
// s34c/s34d: I and L each alone beside a control, after Word crashed during s34b.
// Shapes: reviews/review-632 probe.mts and controls.mts; tests/support/{minimal-docx,story-content-type-specimens,
// relationships-markup-compatibility-specimens}.ts at layer 131.
// Run from the layer 131 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s34a pnpm exec tsx s34builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { STORY_FOOTER_XML, storyContentType, storyReferenceParts } from "./tests/support/story-content-type-specimens";
import {
    DOCUMENT_RELS,
    MCE_DECLARATIONS,
    PACKAGE_RELS,
    fallback,
    wrapRelationship,
} from "./tests/support/relationships-markup-compatibility-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const CT_CORE = "application/vnd.openxmlformats-package.core-properties+xml";
type Parts = Record<string, string>;
const MALFORMED_MAIN = `<?xml version="1.0"?><w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p>`;
const MALFORMED_CORE = `<?xml version="1.0"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">broken`;
const CORE_REL = `<Relationship Id="rIdC" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>`;
const OFFICE_REL = `<Relationship Id="rId1" Type="${R}/officeDocument" Target="word/document.xml"/>`;
const relsWith = (body: string, declarations = "") =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"${declarations ? ` ${declarations}` : ""}>${body}</Relationships>`;
const withCore = (rels: string): Parts => ({
    ...MINIMAL_PARTS,
    [PACKAGE_RELS]: rels,
    "[Content_Types].xml": MINIMAL_PARTS["[Content_Types].xml"]!.replace(
        "</Types>",
        `<Override PartName="/docProps/core.xml" ContentType="${CT_CORE}"/></Types>`,
    ),
    "docProps/core.xml": MALFORMED_CORE,
});
const footer = (ct: "footer" | "header") =>
    storyReferenceParts("footerReference", "footer", "footer1.xml", STORY_FOOTER_XML, storyContentType(ct));
const mainInFallback = () => wrapRelationship({ ...MINIMAL_PARTS }, PACKAGE_RELS, "rId1", fallback);
const control = () => buildDocx({ ...MINIMAL_PARTS });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s34a: [
        ["s34a-control-minimal", "control", control],
        [
            "mce-fallback-main-malformed-doc",
            "#634 (review 632 C: malformed main document, officeDocument relationship in Fallback)",
            () => buildDocx({ ...mainInFallback(), "word/document.xml": MALFORMED_MAIN }),
        ],
        [
            "direct-main-malformed-doc",
            "#634 twin (C: malformed main document, direct relationship)",
            () => buildDocx({ ...MINIMAL_PARTS, "word/document.xml": MALFORMED_MAIN }),
        ],
        [
            "mce-fallback-main-zerobyte-rels",
            "#634 (review 632 D: zero-byte main .rels, officeDocument relationship in Fallback)",
            () => buildDocx({ ...mainInFallback(), [DOCUMENT_RELS]: "" }),
        ],
        [
            "direct-main-zerobyte-rels",
            "#634 twin (D: zero-byte main .rels, direct relationship)",
            () => buildDocx({ ...MINIMAL_PARTS, [DOCUMENT_RELS]: "" }),
        ],
        [
            "mce-fallback-split-duplicate-id",
            "review 632 E (direct rId1 officeDocument plus Fallback rId1 styles in _rels/.rels)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: relsWith(
                        OFFICE_REL + fallback(`<Relationship Id="rId1" Type="${R}/styles" Target="word/styles.xml"/>`),
                        MCE_DECLARATIONS,
                    ),
                }),
        ],
        [
            "direct-duplicate-id",
            "review 632 E twin (two direct rId1 in _rels/.rels)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: relsWith(OFFICE_REL + `<Relationship Id="rId1" Type="${R}/styles" Target="word/styles.xml"/>`),
                }),
        ],
        ["s34a-control-minimal-end", "control", control],
    ],
    s34b: [
        ["s34b-control-minimal", "control", control],
        [
            "mce-fallback-malformed-coreprops",
            "#634 (review 632 F: malformed core properties, relationship in Fallback)",
            () => buildDocx(withCore(relsWith(OFFICE_REL + fallback(CORE_REL), MCE_DECLARATIONS))),
        ],
        [
            "direct-malformed-coreprops",
            "#634 twin (F: malformed core properties, direct relationship)",
            () => buildDocx(withCore(relsWith(OFFICE_REL + CORE_REL))),
        ],
        [
            "mce-fallback-footer-header-ct",
            "#634 (review 632 H: footer typed as a header, relationship in Fallback)",
            () => buildDocx(wrapRelationship(footer("header"), DOCUMENT_RELS, "rIdX", fallback)),
        ],
        [
            "direct-footer-header-ct",
            "#634 twin (H: footer typed as a header, direct relationship; #600)",
            () => buildDocx(footer("header")),
        ],
        [
            "mce-rels-root-mustunderstand",
            "review 632 finding 4 (mc:MustUnderstand of an unknown namespace on the _rels/.rels root)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: MINIMAL_PARTS[PACKAGE_RELS]!.replace(
                        "<Relationships ",
                        `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo" `,
                    ),
                }),
        ],
        [
            "mce-rels-choice-undeclared-prefix",
            "review 632 finding 4 (footer relationship in an mc:Choice whose Requires prefix is undeclared, empty Fallback)",
            () =>
                buildDocx(
                    wrapRelationship(
                        footer("footer"),
                        DOCUMENT_RELS,
                        "rIdX",
                        (rel) => `<mc:AlternateContent><mc:Choice Requires="nope">${rel}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                    ),
                ),
        ],
        ["s34b-control-minimal-end", "control", control],
    ],
    // s34b: Word crashed ("Connection is invalid") twice around its items 4 and 5, so neither of the two finding-4 shapes
    // can be credited with it. Re-probe each alone beside a control.
    s34c: [
        [
            "mce-rels-root-mustunderstand",
            "review 632 finding 4 (re-probe alone)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: MINIMAL_PARTS[PACKAGE_RELS]!.replace(
                        "<Relationships ",
                        `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo" `,
                    ),
                }),
        ],
        ["s34c-control-minimal", "control", control],
    ],
    s34d: [
        [
            "mce-rels-choice-undeclared-prefix",
            "review 632 finding 4 (re-probe alone)",
            () =>
                buildDocx(
                    wrapRelationship(
                        footer("footer"),
                        DOCUMENT_RELS,
                        "rIdX",
                        (rel) => `<mc:AlternateContent><mc:Choice Requires="nope">${rel}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                    ),
                ),
        ],
        ["s34d-control-minimal", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 35's builder (`s35a`–`s35c`) is another standalone script, run the same way from the layer 130 worktree, with `CHUNK` naming the chunk:

```ts
// Session 35 (2026-10-25): the adversarial review of layer 130 (#623, #624, #625; empryo devin/swe-2), its suspected
// findings 5–8, each a shape Word was never shown.
// s35a: finding 5 (#624). A relationship id with no sidecar in a part Word may never read: an unreferenced word/xtra.xml
//       (ISO Strict rs:id, and its Transitional r:id twin, which already blocked before #624), an unreferenced
//       docProps/app.xml (rs:id), an unreached ISO Strict glossary (rs:id footer reference), and word/styles.xml (rs:id
//       on w:name; styles is reached).
// s35b: findings 6 and 7. The no-sidecar walk reads the stored XML: an rs:embed (and its Transitional r:embed twin) inside
//       an mc:Choice Word does not select, and an rs:id footer reference inside w:sectPrChange, each with no sidecar.
//       #623's rule beyond the body w:sectPr: a footer reference with no id inside w:sectPrChange, as a direct w:body
//       child, and in a paragraph-level w:sectPr.
// s35c: finding 8. A footer reference with r:id="" beside x:id="rId9" (urn:x), and one with a whitespace r:id=" ".
// Shapes: wfv-scratch/review-130 probe1–probe3 (N's w:pPr moved first, where the schema puts it); tests/support/minimal-docx.ts.
// Run from the layer 130 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s35a pnpm exec tsx s35builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const WS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const RS = "http://purl.oclc.org/ooxml/officeDocument/relationships";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string, to: string) => {
    if (!text.includes(from)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
const override = (part: string, type: string) =>
    replaceOnce(MINIMAL_PARTS[CT]!, "</Types>", `<Override PartName="/${part}" ContentType="${type}"/></Types>`);
const main = (declarations: string, from: string, to: string): string =>
    replaceOnce(replaceOnce(MINIMAL_PARTS[MAIN]!, "<w:document ", `<w:document ${declarations} `), from, to);
const withoutSidecar = (parts: Parts): Parts => {
    const out = { ...parts };
    delete out[SIDECAR];
    return out;
};
const NOID = '<w:footerReference w:type="default"/>';
const SECTPR_CHANGE = (inner: string) =>
    `<w:sectPrChange w:id="5" w:author="a" w:date="2026-01-01T00:00:00Z"><w:sectPr>${inner}</w:sectPr></w:sectPrChange></w:sectPr>`;
const control = () => buildDocx({ ...MINIMAL_PARTS });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s35a: [
        ["s35a-control-minimal", "control", control],
        [
            "unread-xtra-rs-id-no-sidecar",
            "review 130 finding 5 (#624)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    "word/xtra.xml": `<?xml version="1.0"?><x:root xmlns:x="urn:x" xmlns:rs="${RS}"><x:e rs:id="rId9"/></x:root>`,
                }),
        ],
        [
            "unread-xtra-r-id-no-sidecar",
            "review 130 finding 5 twin (Transitional)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    "word/xtra.xml": `<?xml version="1.0"?><x:root xmlns:x="urn:x" xmlns:r="${R}"><x:e r:id="rId9"/></x:root>`,
                }),
        ],
        [
            "unread-app-props-rs-id-no-sidecar",
            "review 130 finding 5 (#624)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    "docProps/app.xml": `<?xml version="1.0"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:rs="${RS}"><Application rs:id="rId9">x</Application></Properties>`,
                    [CT]: override("docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml"),
                }),
        ],
        [
            "unreached-glossary-rs-id-no-sidecar",
            "review 130 finding 5 (#624)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    "word/glossary/document.xml": `<?xml version="1.0"?><w:glossaryDocument xmlns:w="${WS}" xmlns:rs="${RS}"><w:docParts><w:docPart><w:docPartBody><w:sectPr><w:footerReference w:type="default" rs:id="rId9"/></w:sectPr></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
                    [CT]: override(
                        "word/glossary/document.xml",
                        "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml",
                    ),
                }),
        ],
        [
            "styles-rs-id-no-sidecar",
            "review 130 finding 5 (#624; styles is reached)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    "word/styles.xml": replaceOnce(
                        replaceOnce(MINIMAL_PARTS["word/styles.xml"]!, "<w:styles ", `<w:styles xmlns:rs="${RS}" `),
                        "<w:name ",
                        `<w:name rs:id="rId9" `,
                    ),
                }),
        ],
        ["s35a-control-minimal-end", "control", control],
    ],
    s35b: [
        ["s35b-control-minimal", "control", control],
        [
            "mce-unselected-rs-embed-no-sidecar",
            "review 130 finding 6 (#624)",
            () =>
                buildDocx(
                    withoutSidecar({
                        ...MINIMAL_PARTS,
                        [MAIN]: main(
                            `xmlns:rs="${RS}" xmlns:foo="urn:foo" xmlns:a="${A}"`,
                            "<w:sectPr>",
                            `<mc:AlternateContent><mc:Choice Requires="foo"><w:p><w:r><w:drawing><a:blip rs:embed="rId9"/></w:drawing></w:r></w:p></mc:Choice><mc:Fallback/></mc:AlternateContent><w:sectPr>`,
                        ),
                    }),
                ),
        ],
        [
            "mce-unselected-r-embed-no-sidecar",
            "review 130 finding 6 twin (Transitional)",
            () =>
                buildDocx(
                    withoutSidecar({
                        ...MINIMAL_PARTS,
                        [MAIN]: main(
                            `xmlns:r="${R}" xmlns:foo="urn:foo" xmlns:a="${A}"`,
                            "<w:sectPr>",
                            `<mc:AlternateContent><mc:Choice Requires="foo"><w:p><w:r><w:drawing><a:blip r:embed="rId9"/></w:drawing></w:r></w:p></mc:Choice><mc:Fallback/></mc:AlternateContent><w:sectPr>`,
                        ),
                    }),
                ),
        ],
        [
            "sectprchange-rs-id-no-sidecar",
            "review 130 finding 6 (#624)",
            () =>
                buildDocx(
                    withoutSidecar({
                        ...MINIMAL_PARTS,
                        [MAIN]: main(
                            `xmlns:rs="${RS}"`,
                            "</w:sectPr>",
                            SECTPR_CHANGE('<w:footerReference w:type="default" rs:id="rId9"/>'),
                        ),
                    }),
                ),
        ],
        [
            "sectprchange-footerref-no-id",
            "review 130 finding 7 (#623)",
            () => buildDocx({ ...MINIMAL_PARTS, [MAIN]: main(`xmlns:r="${R}"`, "</w:sectPr>", SECTPR_CHANGE(NOID)) }),
        ],
        [
            "body-child-footerref-no-id",
            "review 130 finding 7 (#623)",
            () => buildDocx({ ...MINIMAL_PARTS, [MAIN]: main(`xmlns:r="${R}"`, "<w:sectPr>", `${NOID}<w:sectPr>`) }),
        ],
        [
            "ppr-sectpr-footerref-no-id",
            "review 130 finding 7 (#623)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [MAIN]: main(`xmlns:r="${R}"`, "<w:r><w:t>Hello", `<w:pPr><w:sectPr>${NOID}</w:sectPr></w:pPr><w:r><w:t>Hello`),
                }),
        ],
        ["s35b-control-minimal-end", "control", control],
    ],
    s35c: [
        ["s35c-control-minimal", "control", control],
        [
            "footerref-rid-empty-x-id",
            "review 130 finding 8 (#623)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [MAIN]: main(
                        `xmlns:r="${R}" xmlns:x="urn:x"`,
                        "<w:sectPr>",
                        '<w:sectPr><w:footerReference w:type="default" r:id="" x:id="rId9"/>',
                    ),
                }),
        ],
        [
            "footerref-rid-whitespace",
            "review 130 finding 8 (#623)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [MAIN]: main(`xmlns:r="${R}"`, "<w:sectPr>", '<w:sectPr><w:footerReference w:type="default" r:id=" "/>'),
                }),
        ],
        ["s35c-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        const r = await validate(path.join(dir, file), { profile });
        return {
            valid: r.valid,
            errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
        };
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 36's builder (`s36a`–`s36e`) is another standalone script, run the same way from the layer 131 worktree, with `CHUNK` naming the chunk:

```ts
// Session 36 (2026-10-25): the adversarial review of #636's fix (66d774b3; empryo devin/swe-2), suspected findings S1–S6,
// and the #638 rework's conservative boundary. Each is a shape Word was never shown.
// s36a: malformed markup compatibility (an mc:AlternateContent whose mc:Choice Requires an undeclared prefix, with an empty
//       mc:Fallback) added as a sibling that removes no relationship. s34d saw recovery for this class only where it also
//       removed the footer relationship, so it cannot say which of the two Word refused. In the main document's .rels, in
//       _rels/.rels (S3), in a reached glossary's .rels (S1), and in a word/_rels/document.xml.rels no main document owns
//       (S2: the main document stored as word/doc2.xml).
// s36b: mc:MustUnderstand="foo" on a Relationship element of _rels/.rels (S4; s34c put it on the root), on the
//       word/_rels/document.xml.rels root (S6), and two other malformed shapes in the main document's .rels (S5: a Fallback
//       with no Choice, and a foreign child of mc:AlternateContent), each keeping the styles relationship. Then #638's
//       boundary: a chart part with c:externalData r:id and no .rels, related by a chart relationship, stored outside word/
//       and under it.
// s36c: the adversarial review of layer 131 (#634, #635; pi glm-5.3), suspected findings S2–S4 and the shape behind
//       proven finding P1 (#640): a _rels/.rels whose root is an mc:AlternateContent with the whole Relationships
//       element in its Fallback (S3), or with two bare Relationship elements there (#640: processing leaves two roots);
//       session 26's footer relationship inside an ignorable x:Wrap that mc:ProcessContent names (S2) and inside one it
//       does not (S2's mirror, where markup compatibility drops the relationship); and an rId2 in both an understood
//       w14 mc:Choice and its mc:Fallback beside the direct officeDocument rId1 (S4: a duplicate only in the stored
//       bytes).
// s36d: what s36a–s36c left open. A chart that an inline drawing in word/document.xml references (s36b's charts were
//       related but referenced by nothing), with no chart sidecar while c:externalData names rId1, in word/ and outside
//       it, and with no c:externalData (the drawing's own control); and the s36a malformed AlternateContent sibling in
//       the sidecar of a Word-read non-story part (styles) and of a story part (footer).
// s36e: whether s36a's rule follows the relationship or the path: the main document stored as word/doc2.xml with the
//       malformed sibling, and with mc:MustUnderstand, in its own sidecar word/_rels/doc2.xml.rels; mc:MustUnderstand
//       on a stray word/_rels/document.xml.rels root (s36a's stray shape); and on the glossary document's sidecar root.
// Shapes: wfv-scratch/review-636 probe4/probe6/probe7/probe8 and the probe of documentRelsRootMustUnderstand;
// wfv-scratch/review-131 matrix.mjs, run-p2-stack.mjs and run-p14.mjs; tests/support/minimal-docx.ts,
// story-content-type-specimens.ts and relationships-markup-compatibility-specimens.ts.
// Run from the layer 131 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s36a pnpm exec tsx s36builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import {
    STORY_FOOTER_XML,
    glossaryStoryReferenceParts,
    storyContentType,
    storyReferenceParts,
} from "./tests/support/story-content-type-specimens";
import { MCE_DECLARATIONS, wrapRelationship } from "./tests/support/relationships-markup-compatibility-specimens";
import { validate } from "./src/scripts/office/validate";

const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const CT = "[Content_Types].xml";
const PACKAGE_RELS = "_rels/.rels";
const SIDECAR = "word/_rels/document.xml.rels";
const GLOSSARY_SIDECAR = "word/glossary/_rels/document.xml.rels";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string | RegExp, to: string) => {
    if (typeof from === "string" ? !text.includes(from) : !from.test(text)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
// The undeclared-Requires AlternateContent, as a sibling: it selects nothing and removes no relationship.
const MALFORMED_SIBLING = '<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent></Relationships>';
const withSibling = (rels: string): string =>
    replaceOnce(replaceOnce(rels, "<Relationships ", `<Relationships xmlns:mc="${MC}" `), "</Relationships>", MALFORMED_SIBLING);
const STYLES_REL = /<Relationship Id="rId1"[^>]*\/>/;
const STYLES_REL_XML = `<Relationship Id="rId1" Type="${R}/styles" Target="styles.xml"/>`;
const chart = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart><c:externalData r:id="rId1"/></c:chartSpace>`;
const chartParts = (part: string, target: string): Parts => ({
    ...MINIMAL_PARTS,
    [part]: chart,
    [SIDECAR]: replaceOnce(
        MINIMAL_PARTS[SIDECAR]!,
        "</Relationships>",
        `<Relationship Id="rId9" Type="${R}/chart" Target="${target}"/></Relationships>`,
    ),
    [CT]: replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `<Override PartName="/${part}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/></Types>`,
    ),
});
const control = () => buildDocx({ ...MINIMAL_PARTS });
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
const OFFICE_REL = `<Relationship Id="rId1" Type="${R}/officeDocument" Target="word/document.xml"/>`;
const footer = () => storyReferenceParts("footerReference", "footer", "footer1.xml", STORY_FOOTER_XML, storyContentType("footer")) as Parts;
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const BAR_PLOT_AREA =
    '<c:plotArea><c:layout/><c:barChart><c:barDir val="col"/><c:grouping val="clustered"/><c:ser><c:idx val="0"/><c:order val="0"/>' +
    '<c:val><c:numLit><c:ptCount val="1"/><c:pt idx="0"><c:v>1</c:v></c:pt></c:numLit></c:val></c:ser><c:axId val="1"/><c:axId val="2"/></c:barChart>' +
    '<c:catAx><c:axId val="1"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="b"/><c:crossAx val="2"/></c:catAx>' +
    '<c:valAx><c:axId val="2"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="l"/><c:crossAx val="1"/></c:valAx></c:plotArea>';
const barChart = (externalData: boolean) =>
    `${XML_DECLARATION}<c:chartSpace xmlns:c="${C}" xmlns:a="${A}" xmlns:r="${R}"><c:chart>${BAR_PLOT_AREA}</c:chart>${externalData ? '<c:externalData r:id="rId1"/>' : ""}</c:chartSpace>`;
const CHART_DRAWING =
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">' +
    '<c:chart r:id="rId9"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>';
const referencedChartParts = (part: string, target: string, externalData: boolean): Parts => ({
    ...chartParts(part, target),
    [part]: barChart(externalData),
    "word/document.xml": replaceOnce(
        replaceOnce(
            MINIMAL_PARTS["word/document.xml"]!,
            "<w:document ",
            `<w:document xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:r="${R}" `,
        ),
        "<w:sectPr>",
        `${CHART_DRAWING}<w:sectPr>`,
    ),
});
const MUST_UNDERSTAND_ROOT = (rels: string) =>
    replaceOnce(rels, "<Relationships ", `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo" `);
const renamedMain = (sidecar: (rels: string) => string, stray?: (rels: string) => string): Parts => {
    const parts: Parts = {
        ...MINIMAL_PARTS,
        [PACKAGE_RELS]: replaceOnce(MINIMAL_PARTS[PACKAGE_RELS]!, 'Target="word/document.xml"', 'Target="word/doc2.xml"'),
        [CT]: replaceOnce(MINIMAL_PARTS[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/doc2.xml"'),
        "word/doc2.xml": MINIMAL_PARTS["word/document.xml"]!,
        "word/_rels/doc2.xml.rels": sidecar(MINIMAL_PARTS[SIDECAR]!),
    };
    delete parts["word/document.xml"];
    delete parts[SIDECAR];
    if (stray) {
        parts["word/document.xml"] = MINIMAL_PARTS["word/document.xml"]!;
        parts[SIDECAR] = stray(MINIMAL_PARTS[SIDECAR]!);
    }
    return parts;
};
const EMPTY_RELS = `${XML_DECLARATION}<Relationships xmlns="${PR}"></Relationships>`;
const wrapFooter = (declarations: string) => wrapRelationship(footer(), SIDECAR, "rIdX", (rel) => `<x:Wrap>${rel}</x:Wrap>`, declarations);

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s36a: [
        ["s36a-control-minimal", "control", control],
        [
            "docrels-mc-malformed-sibling",
            "s34d discriminator (#636)",
            () => buildDocx({ ...MINIMAL_PARTS, [SIDECAR]: withSibling(MINIMAL_PARTS[SIDECAR]!) }),
        ],
        [
            "pkgrels-mc-malformed-sibling",
            "review of #636, S3",
            () => buildDocx({ ...MINIMAL_PARTS, [PACKAGE_RELS]: withSibling(MINIMAL_PARTS[PACKAGE_RELS]!) }),
        ],
        [
            "glossary-rels-mc-malformed-sibling",
            "review of #636, S1",
            () => {
                const glossary = glossaryStoryReferenceParts(
                    "footerReference",
                    "footer",
                    "footer9.xml",
                    STORY_FOOTER_XML,
                    storyContentType("footer"),
                ) as Parts;
                return buildDocx({ ...glossary, [GLOSSARY_SIDECAR]: withSibling(glossary[GLOSSARY_SIDECAR]!) });
            },
        ],
        [
            "stray-docrels-mc-malformed-sibling",
            "review of #636, S2",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: replaceOnce(MINIMAL_PARTS[PACKAGE_RELS]!, 'Target="word/document.xml"', 'Target="word/doc2.xml"'),
                    [CT]: replaceOnce(MINIMAL_PARTS[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/doc2.xml"'),
                    "word/doc2.xml": MINIMAL_PARTS["word/document.xml"]!,
                    "word/_rels/doc2.xml.rels": MINIMAL_PARTS[SIDECAR]!,
                    [SIDECAR]: withSibling(MINIMAL_PARTS[SIDECAR]!),
                }),
        ],
        ["s36a-control-minimal-end", "control", control],
    ],
    s36b: [
        ["s36b-control-minimal", "control", control],
        [
            "pkgrels-relationship-mustunderstand",
            "review of #636, S4",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: replaceOnce(
                        replaceOnce(
                            MINIMAL_PARTS[PACKAGE_RELS]!,
                            "<Relationships ",
                            `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" `,
                        ),
                        '<Relationship Id="rId1"',
                        '<Relationship Id="rId1" mc:MustUnderstand="foo"',
                    ),
                }),
        ],
        [
            "docrels-root-mustunderstand",
            "review of #636, S6",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [SIDECAR]: replaceOnce(
                        MINIMAL_PARTS[SIDECAR]!,
                        "<Relationships ",
                        `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo" `,
                    ),
                }),
        ],
        [
            "docrels-mc-fallback-only",
            "review of #636, S5",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [SIDECAR]: replaceOnce(
                        replaceOnce(MINIMAL_PARTS[SIDECAR]!, "<Relationships ", `<Relationships xmlns:mc="${MC}" `),
                        STYLES_REL,
                        `<mc:AlternateContent><mc:Fallback>${STYLES_REL_XML}</mc:Fallback></mc:AlternateContent>`,
                    ),
                }),
        ],
        [
            "docrels-mc-foreign-branch",
            "review of #636, S5",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [SIDECAR]: replaceOnce(
                        replaceOnce(MINIMAL_PARTS[SIDECAR]!, "<Relationships ", `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" `),
                        STYLES_REL,
                        `<mc:AlternateContent><foo:bar/><mc:Fallback>${STYLES_REL_XML}</mc:Fallback></mc:AlternateContent>`,
                    ),
                }),
        ],
        [
            "chart-outside-word-related-no-sidecar",
            "#638 boundary",
            () => buildDocx(chartParts("charts/chart1.xml", "../charts/chart1.xml")),
        ],
        ["chart-word-related-no-sidecar", "#638 boundary twin", () => buildDocx(chartParts("word/charts/chart1.xml", "charts/chart1.xml"))],
        ["s36b-control-minimal-end", "control", control],
    ],
    s36c: [
        ["s36c-control-minimal", "control", control],
        [
            "pkgrels-root-ac-fallback-relationships",
            "review of layer 131, S3",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: `${XML_DECLARATION}<mc:AlternateContent xmlns:mc="${MC}" xmlns:foo="urn:foo"><mc:Choice Requires="foo"/><mc:Fallback>${MINIMAL_PARTS[PACKAGE_RELS]!.replace(XML_DECLARATION, "")}</mc:Fallback></mc:AlternateContent>`,
                }),
        ],
        [
            "pkgrels-root-ac-fallback-two-relationships",
            "#640 (review of layer 131, P1)",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: `${XML_DECLARATION}<mc:AlternateContent xmlns:mc="${MC}" xmlns:foo="urn:foo"><mc:Choice Requires="foo"/><mc:Fallback><Relationship xmlns="${PR}" Id="rId1" Type="${R}/officeDocument" Target="word/document.xml"/><Relationship xmlns="${PR}" Id="rId2" Type="${R}/styles" Target="word/styles.xml"/></mc:Fallback></mc:AlternateContent>`,
                }),
        ],
        [
            "docrels-processcontent-wrapper-footer",
            "review of layer 131, S2",
            () => buildDocx(wrapFooter(`xmlns:mc="${MC}" xmlns:x="urn:x" mc:Ignorable="x" mc:ProcessContent="x:Wrap"`)),
        ],
        [
            "docrels-ignorable-wrapper-footer",
            "review of layer 131, S2 mirror",
            () => buildDocx(wrapFooter(`xmlns:mc="${MC}" xmlns:x="urn:x" mc:Ignorable="x"`)),
        ],
        [
            "pkgrels-dup-id-choice-fallback",
            "review of layer 131, S4",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [PACKAGE_RELS]: replaceOnce(
                        replaceOnce(MINIMAL_PARTS[PACKAGE_RELS]!, "<Relationships ", `<Relationships ${MCE_DECLARATIONS} `),
                        OFFICE_REL,
                        `${OFFICE_REL}<mc:AlternateContent><mc:Choice Requires="w14"><Relationship Id="rId2" Type="${R}/styles" Target="word/styles.xml"/></mc:Choice><mc:Fallback><Relationship Id="rId2" Type="${R}/styles" Target="word/styles.xml"/></mc:Fallback></mc:AlternateContent>`,
                    ),
                }),
        ],
        ["s36c-control-minimal-end", "control", control],
    ],
    s36d: [
        ["s36d-control-minimal", "control", control],
        [
            "chart-word-referenced-no-externaldata-no-sidecar",
            "drawing control for s36d",
            () => buildDocx(referencedChartParts("word/charts/chart1.xml", "charts/chart1.xml", false)),
        ],
        [
            "chart-word-referenced-no-sidecar",
            "#638 boundary, referenced",
            () => buildDocx(referencedChartParts("word/charts/chart1.xml", "charts/chart1.xml", true)),
        ],
        [
            "chart-outside-word-referenced-no-sidecar",
            "#638 boundary, referenced, outside word/",
            () => buildDocx(referencedChartParts("charts/chart1.xml", "../charts/chart1.xml", true)),
        ],
        [
            "styles-rels-mc-malformed-sibling",
            "scope of #636, Word-read non-story part",
            () => buildDocx({ ...MINIMAL_PARTS, "word/_rels/styles.xml.rels": withSibling(EMPTY_RELS) }),
        ],
        [
            "footer-rels-mc-malformed-sibling",
            "scope of #636, story part",
            () => buildDocx({ ...footer(), "word/_rels/footer1.xml.rels": withSibling(EMPTY_RELS) }),
        ],
        ["s36d-control-minimal-end", "control", control],
    ],
    s36e: [
        ["s36e-control-minimal", "control", control],
        ["renamed-main-control", "control for s36e's renamed main document", () => buildDocx(renamedMain((rels) => rels))],
        ["renamed-main-rels-mc-malformed-sibling", "scope of #636, by relationship", () => buildDocx(renamedMain(withSibling))],
        ["renamed-main-rels-root-mustunderstand", "scope of #636, by relationship", () => buildDocx(renamedMain(MUST_UNDERSTAND_ROOT))],
        [
            "stray-docrels-root-mustunderstand",
            "scope of #636, stray sidecar",
            () => buildDocx(renamedMain((rels) => rels, MUST_UNDERSTAND_ROOT)),
        ],
        [
            "glossary-rels-root-mustunderstand",
            "scope of #636, glossary sidecar",
            () => {
                const glossary = glossaryStoryReferenceParts(
                    "footerReference",
                    "footer",
                    "footer9.xml",
                    STORY_FOOTER_XML,
                    storyContentType("footer"),
                ) as Parts;
                return buildDocx({ ...glossary, [GLOSSARY_SIDECAR]: MUST_UNDERSTAND_ROOT(glossary[GLOSSARY_SIDECAR]!) });
            },
        ],
        ["s36e-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        // #640: validate() throws on some shapes at the built commit; record the throw instead of stopping.
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 37's builder (`s37a`, `s37b`) is another standalone script, run the same way from #644's and #645's lane worktrees, with `CHUNK` naming the chunk:

```ts
// Session 37 (2026-10-25): the relationships parts #644 leaves unobserved. s36d showed the malformed AlternateContent
// sibling opening clean in the styles and footer sidecars; #644 extends that warning to every other sidecar that is
// not a story root's. s37a shows Word the same sibling in the sidecars of settings, numbering and a header, beside a
// control holding settings and numbering without sidecars, and mc:MustUnderstand on the root of the styles and footer
// sidecars (s36e observed it only on story-root and stray sidecars).
// Run from the layer 131 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s37a pnpm exec tsx s37builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import {
    STORY_FOOTER_XML,
    STORY_HEADER_XML,
    glossaryStoryReferenceParts,
    storyContentType,
    storyReferenceParts,
} from "./tests/support/story-content-type-specimens";
import { MCE_DECLARATIONS, wrapRelationship } from "./tests/support/relationships-markup-compatibility-specimens";
import { validate } from "./src/scripts/office/validate";

const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const CT = "[Content_Types].xml";
const PACKAGE_RELS = "_rels/.rels";
const SIDECAR = "word/_rels/document.xml.rels";
const GLOSSARY_SIDECAR = "word/glossary/_rels/document.xml.rels";
type Parts = Record<string, string>;
const replaceOnce = (text: string, from: string | RegExp, to: string) => {
    if (typeof from === "string" ? !text.includes(from) : !from.test(text)) throw new Error(`missing ${from}`);
    return text.replace(from, to);
};
// The undeclared-Requires AlternateContent, as a sibling: it selects nothing and removes no relationship.
const MALFORMED_SIBLING = '<mc:AlternateContent><mc:Choice Requires="nope"/><mc:Fallback/></mc:AlternateContent></Relationships>';
const withSibling = (rels: string): string =>
    replaceOnce(replaceOnce(rels, "<Relationships ", `<Relationships xmlns:mc="${MC}" `), "</Relationships>", MALFORMED_SIBLING);
const STYLES_REL = /<Relationship Id="rId1"[^>]*\/>/;
const STYLES_REL_XML = `<Relationship Id="rId1" Type="${R}/styles" Target="styles.xml"/>`;
const chart = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart><c:externalData r:id="rId1"/></c:chartSpace>`;
const chartParts = (part: string, target: string): Parts => ({
    ...MINIMAL_PARTS,
    [part]: chart,
    [SIDECAR]: replaceOnce(
        MINIMAL_PARTS[SIDECAR]!,
        "</Relationships>",
        `<Relationship Id="rId9" Type="${R}/chart" Target="${target}"/></Relationships>`,
    ),
    [CT]: replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `<Override PartName="/${part}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/></Types>`,
    ),
});
const control = () => buildDocx({ ...MINIMAL_PARTS });
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
const OFFICE_REL = `<Relationship Id="rId1" Type="${R}/officeDocument" Target="word/document.xml"/>`;
const footer = () => storyReferenceParts("footerReference", "footer", "footer1.xml", STORY_FOOTER_XML, storyContentType("footer")) as Parts;
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const BAR_PLOT_AREA =
    '<c:plotArea><c:layout/><c:barChart><c:barDir val="col"/><c:grouping val="clustered"/><c:ser><c:idx val="0"/><c:order val="0"/>' +
    '<c:val><c:numLit><c:ptCount val="1"/><c:pt idx="0"><c:v>1</c:v></c:pt></c:numLit></c:val></c:ser><c:axId val="1"/><c:axId val="2"/></c:barChart>' +
    '<c:catAx><c:axId val="1"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="b"/><c:crossAx val="2"/></c:catAx>' +
    '<c:valAx><c:axId val="2"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="l"/><c:crossAx val="1"/></c:valAx></c:plotArea>';
const barChart = (externalData: boolean) =>
    `${XML_DECLARATION}<c:chartSpace xmlns:c="${C}" xmlns:a="${A}" xmlns:r="${R}"><c:chart>${BAR_PLOT_AREA}</c:chart>${externalData ? '<c:externalData r:id="rId1"/>' : ""}</c:chartSpace>`;
const CHART_DRAWING =
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">' +
    '<c:chart r:id="rId9"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>';
const referencedChartParts = (part: string, target: string, externalData: boolean): Parts => ({
    ...chartParts(part, target),
    [part]: barChart(externalData),
    "word/document.xml": replaceOnce(
        replaceOnce(
            MINIMAL_PARTS["word/document.xml"]!,
            "<w:document ",
            `<w:document xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:r="${R}" `,
        ),
        "<w:sectPr>",
        `${CHART_DRAWING}<w:sectPr>`,
    ),
});
const MUST_UNDERSTAND_ROOT = (rels: string) =>
    replaceOnce(rels, "<Relationships ", `<Relationships xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo" `);
const renamedMain = (sidecar: (rels: string) => string, stray?: (rels: string) => string): Parts => {
    const parts: Parts = {
        ...MINIMAL_PARTS,
        [PACKAGE_RELS]: replaceOnce(MINIMAL_PARTS[PACKAGE_RELS]!, 'Target="word/document.xml"', 'Target="word/doc2.xml"'),
        [CT]: replaceOnce(MINIMAL_PARTS[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/doc2.xml"'),
        "word/doc2.xml": MINIMAL_PARTS["word/document.xml"]!,
        "word/_rels/doc2.xml.rels": sidecar(MINIMAL_PARTS[SIDECAR]!),
    };
    delete parts["word/document.xml"];
    delete parts[SIDECAR];
    if (stray) {
        parts["word/document.xml"] = MINIMAL_PARTS["word/document.xml"]!;
        parts[SIDECAR] = stray(MINIMAL_PARTS[SIDECAR]!);
    }
    return parts;
};
const EMPTY_RELS = `${XML_DECLARATION}<Relationships xmlns="${PR}"></Relationships>`;
const wrapFooter = (declarations: string) => wrapRelationship(footer(), SIDECAR, "rIdX", (rel) => `<x:Wrap>${rel}</x:Wrap>`, declarations);

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const withWordPart = (parts: Parts, file: string, type: string, ct: string, xml: string, id: string): Parts => ({
    ...parts,
    [`word/${file}`]: xml,
    [SIDECAR]: replaceOnce(
        parts[SIDECAR]!,
        "</Relationships>",
        `<Relationship Id="${id}" Type="${R}/${type}" Target="${file}"/></Relationships>`,
    ),
    [CT]: replaceOnce(
        parts[CT]!,
        "</Types>",
        `<Override PartName="/word/${file}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${ct}+xml"/></Types>`,
    ),
});
const withSettings = (parts: Parts): Parts =>
    withWordPart(parts, "settings.xml", "settings", "settings", `${XML_DECLARATION}<w:settings xmlns:w="${W}"/>`, "rId7");
const withNumbering = (parts: Parts): Parts =>
    withWordPart(parts, "numbering.xml", "numbering", "numbering", `${XML_DECLARATION}<w:numbering xmlns:w="${W}"/>`, "rId8");
const header = () => storyReferenceParts("headerReference", "header", "header1.xml", STORY_HEADER_XML, storyContentType("header")) as Parts;

// s37b (#645): a chart drawing inside an mc:AlternateContent, selected (Requires="w14", understood) or not
// (Requires="foo", unknown, empty Fallback), and a chart outside word/ reached by a chart and an image relationship.
const CHART_INSIDE = "word/charts/chart1.xml";
const CHART_OUTSIDE = "charts/chart1.xml";
const choiceWrappedChart = (requires: string, externalData: boolean): Parts => {
    const parts = referencedChartParts(CHART_INSIDE, "charts/chart1.xml", externalData);
    const main =
        requires === "foo"
            ? replaceOnce(parts["word/document.xml"]!, "<w:document ", '<w:document xmlns:foo="urn:foo" ')
            : parts["word/document.xml"]!;
    return {
        ...parts,
        "word/document.xml": replaceOnce(
            main,
            CHART_DRAWING,
            `<mc:AlternateContent><mc:Choice Requires="${requires}">${CHART_DRAWING}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
        ),
    };
};
const mixedReachChart = (): Parts => {
    const parts = chartParts(CHART_OUTSIDE, `../${CHART_OUTSIDE}`);
    return {
        ...parts,
        [SIDECAR]: replaceOnce(
            parts[SIDECAR]!,
            "</Relationships>",
            `<Relationship Id="rId8" Type="${R}/image" Target="../${CHART_OUTSIDE}"/></Relationships>`,
        ),
    };
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s37a: [
        ["s37a-control-minimal", "control", control],
        ["settings-numbering-control", "control for s37a", () => buildDocx(withNumbering(withSettings({ ...MINIMAL_PARTS })))],
        [
            "settings-rels-mc-malformed-sibling",
            "scope of #644, settings sidecar",
            () => buildDocx({ ...withSettings({ ...MINIMAL_PARTS }), "word/_rels/settings.xml.rels": withSibling(EMPTY_RELS) }),
        ],
        [
            "numbering-rels-mc-malformed-sibling",
            "scope of #644, numbering sidecar",
            () => buildDocx({ ...withNumbering({ ...MINIMAL_PARTS }), "word/_rels/numbering.xml.rels": withSibling(EMPTY_RELS) }),
        ],
        [
            "header-rels-mc-malformed-sibling",
            "scope of #644, header sidecar",
            () => buildDocx({ ...header(), "word/_rels/header1.xml.rels": withSibling(EMPTY_RELS) }),
        ],
        [
            "styles-rels-root-mustunderstand",
            "scope of #644, styles sidecar root",
            () => buildDocx({ ...MINIMAL_PARTS, "word/_rels/styles.xml.rels": MUST_UNDERSTAND_ROOT(EMPTY_RELS) }),
        ],
        [
            "footer-rels-root-mustunderstand",
            "scope of #644, footer sidecar root",
            () => buildDocx({ ...footer(), "word/_rels/footer1.xml.rels": MUST_UNDERSTAND_ROOT(EMPTY_RELS) }),
        ],
        ["s37a-control-minimal-end", "control", control],
    ],
    s37b: [
        ["s37b-control-minimal", "control", control],
        [
            "chart-word-unselected-reference-no-sidecar",
            "#645 derived: chart drawing only in an unselected mc:Choice",
            () => buildDocx(choiceWrappedChart("foo", true)),
        ],
        [
            "chart-word-selected-reference-no-sidecar",
            "#645 twin: chart drawing in a selected mc:Choice",
            () => buildDocx(choiceWrappedChart("w14", true)),
        ],
        [
            "chart-word-selected-reference-no-externaldata",
            "control for the selected twin: no dangling externalData",
            () => buildDocx(choiceWrappedChart("w14", false)),
        ],
        [
            "chart-outside-word-mixed-reach-no-sidecar",
            "#645 derived: chart reached by chart and image relationships",
            () => buildDocx(mixedReachChart()),
        ],
        ["s37b-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        // #640: validate() throws on some shapes at the built commit; record the throw instead of stopping.
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 38's builder (`s38a`) is another standalone script, run the same way from #646's lane worktree, with `CHUNK` naming the chunk:

```ts
// Session 38 (2026-10-25): the package relationships root wrappers #646's fix accepts without evidence. s36c showed
// Word a _rels/.rels root mc:AlternateContent whose Fallback holds the whole Relationships element (clean open) and
// one whose Fallback holds two Relationship elements (recovery). #646's lane judges the package part's root on the
// processed view, so every wrapper that resolves to exactly one Relationships passes, including a selected
// mc:Choice and an Ignorable mc:ProcessContent wrapper that Word has not been shown. s38a shows Word those two, the
// s36c clean shape again, and a Choice Word does not select (zero elements, still rejected), between controls.
// Run from the #646 lane worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s38a pnpm exec tsx s38builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const PACKAGE_RELS = "_rels/.rels";
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
// The package part's own Relationships element, without its XML declaration.
const RELATIONSHIPS = MINIMAL_PARTS[PACKAGE_RELS]!.replace(XML_DECLARATION, "");
if (RELATIONSHIPS === MINIMAL_PARTS[PACKAGE_RELS]) throw new Error("the package part lost its XML declaration");
const wrapped = (root: string) => buildDocx({ ...MINIMAL_PARTS, [PACKAGE_RELS]: `${XML_DECLARATION}${root}` });
const control = () => buildDocx({ ...MINIMAL_PARTS });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s38a: [
        ["s38a-control-minimal", "control", control],
        [
            "pkgrels-root-ac-fallback-relationships-recheck",
            "#646 observed shape (s36c), again",
            () =>
                wrapped(
                    `<mc:AlternateContent xmlns:mc="${MC}" xmlns:foo="urn:foo"><mc:Choice Requires="foo"/><mc:Fallback>${RELATIONSHIPS}</mc:Fallback></mc:AlternateContent>`,
                ),
        ],
        [
            "pkgrels-root-ac-choice-relationships",
            "#646 unobserved: selected mc:Choice holds the Relationships element",
            () =>
                wrapped(
                    `<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">${RELATIONSHIPS}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                ),
        ],
        [
            "pkgrels-root-processcontent-relationships",
            "#646 unobserved: Ignorable ProcessContent wrapper holds the Relationships element",
            () => wrapped(`<x:Wrap xmlns:mc="${MC}" xmlns:x="urn:x" mc:Ignorable="x" mc:ProcessContent="x:Wrap">${RELATIONSHIPS}</x:Wrap>`),
        ],
        [
            "pkgrels-root-ac-unselected-choice-relationships",
            "#646 boundary: unselected mc:Choice holds it, empty Fallback",
            () =>
                wrapped(
                    `<mc:AlternateContent xmlns:mc="${MC}" xmlns:foo="urn:foo"><mc:Choice Requires="foo">${RELATIONSHIPS}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                ),
        ],
        ["s38a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 39's builder (`s39a`, `s39b`, `s39c`) is another standalone script, run the same way from the layer 133 worktree, with `CHUNK` naming the chunk:

```ts
// Session 39 (2026-10-25): the shapes layer 133's review (F1, F2) found #645's and #646's fixes accept without
// evidence. #645 demotes a chart part's missing sidecar whenever no Word-read part's effective XML names one of its
// chart relationships; sessions 36-37 showed Word only the main document's sidecar, a direct drawing and a drawing in
// a selected or unselected mc:Choice. #646 judges the package relationships root on the processed view; session 38
// showed Word three single wrappers. s39a shows Word the six unreferenced chart shapes whose verdict flipped (#661),
// s39b the six compound package-root wrappers (#662), and s39c the referenced twins of the s39a shapes, which still
// block, so each s39a row has a paired observation. Shapes follow the review's builder (review-133/build-specimens.mts).
// Run from the layer 133 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s39a pnpm exec tsx s39builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import {
    CHART_CONTENT_TYPE,
    CHART_DRAWING,
    barChartXml,
    chartSpecimenParts,
    referencedChartSpecimenParts,
} from "./tests/support/chart-specimens";
import { glossaryStoryParts } from "./tests/support/glossary-content-type-specimens";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { storyContentType, storyContentTypeParts } from "./tests/support/story-content-type-specimens";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const DR = "word/_rels/document.xml.rels";
const CH = "word/charts/chart1.xml";
const PK = "_rels/.rels";
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
const replaceOnce = (text: string, from: string | RegExp, to: string): string => {
    const next = text.replace(from, to);
    if (next === text) throw new Error(`missing ${from}`);
    return next;
};
const rel = (id: string, type: string, target: string) => `<Relationship Id="${id}" Type="${R}/${type}" Target="${target}"/>`;
const rels = (body: string) => `${XML_DECLARATION}<Relationships xmlns="${PR}">${body}</Relationships>`;

// A chart related from a reached story's sidecar as rId9; `referenced` puts CHART_DRAWING before the story's first paragraph.
const storyChart = (source: "header" | "footnote" | "glossary", referenced: boolean) => {
    let p: Record<string, string>, part: string, side: string;
    if (source === "header") {
        p = storyContentTypeParts("header", storyContentType("header"));
        part = "word/header9.xml";
        side = "word/_rels/header9.xml.rels";
    } else {
        p = glossaryStoryParts("footnotes", true, true);
        part = source === "glossary" ? "word/glossary/document.xml" : "word/glossary/footnotes.xml";
        side = source === "glossary" ? "word/glossary/_rels/document.xml.rels" : "word/glossary/_rels/footnotes.xml.rels";
    }
    p[CH] = barChartXml(true);
    p[CT] = replaceOnce(p[CT]!, "</Types>", `<Override PartName="/${CH}" ContentType="${CHART_CONTENT_TYPE}"/></Types>`);
    p[side] = replaceOnce(
        p[side] ?? rels(""),
        "</Relationships>",
        rel("rId9", "chart", source === "header" ? "charts/chart1.xml" : "../charts/chart1.xml") + "</Relationships>",
    );
    if (referenced) {
        let xml = replaceOnce(
            p[part]!,
            /(<w:\w+)(\s)/,
            `$1 xmlns:w14="${W14}" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"$2`,
        );
        xml = xml.replaceAll(` xmlns:r="${R}"`, "");
        xml = replaceOnce(xml, /(<w:\w+)/, `$1 xmlns:r="${R}"`);
        p[part] = replaceOnce(xml, "<w:p>", CHART_DRAWING + "<w:p>");
    }
    return buildDocx(p);
};
// The main document's drawing behind an mc:Fallback: `selected` puts an unselected Choice before it.
const fallbackChart = (selected: boolean) => {
    const p = referencedChartSpecimenParts(CH, "charts/chart1.xml", true);
    p[MAIN] = replaceOnce(
        replaceOnce(
            p[MAIN]!,
            CHART_DRAWING,
            `<mc:AlternateContent><mc:Choice Requires="${selected ? "foo" : "w14"}"/><mc:Fallback>${CHART_DRAWING}</mc:Fallback></mc:AlternateContent>`,
        ),
        "<w:document ",
        '<w:document xmlns:foo="urn:foo" ',
    );
    return buildDocx(p);
};
// A second chart relationship rId8 to the same part.
const twoRelationships = (referenced: boolean) => {
    const p = referenced ? referencedChartSpecimenParts(CH, "charts/chart1.xml", true) : chartSpecimenParts(CH, "charts/chart1.xml");
    p[DR] = replaceOnce(p[DR]!, "</Relationships>", rel("rId8", "chart", "charts/chart1.xml") + "</Relationships>");
    return buildDocx(p);
};
// The relationship targets an OPC-equivalent spelling of the stored chart name.
const equivalentTarget = (referenced: boolean) => {
    const p = referenced ? referencedChartSpecimenParts(CH, "charts/chart1.xml", true) : chartSpecimenParts(CH, "charts/chart1.xml");
    p[DR] = replaceOnce(p[DR]!, 'Target="charts/chart1.xml"', 'Target="CHARTS/%63hart1.xml"');
    return buildDocx(p);
};

const DECL = `xmlns:mc="${MC}" xmlns:foo="urn:foo" xmlns:w14="${W14}"`;
// The package part's own Relationships element, without its XML declaration.
const PLAIN = replaceOnce(MINIMAL_PARTS[PK]!, XML_DECLARATION, "");
const wrap = (xml: string) =>
    `<mc:AlternateContent ${DECL}><mc:Choice Requires="foo"/><mc:Fallback>${xml}</mc:Fallback></mc:AlternateContent>`;
const packageRoot = (root: string) => buildDocx({ ...MINIMAL_PARTS, [PK]: `${XML_DECLARATION}${root}` });
const control = () => buildDocx({ ...MINIMAL_PARTS });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s39a: [
        ["s39a-control-minimal", "control", control],
        [
            "chart-header-unreferenced",
            "#661: chart related from a referenced header's sidecar, Id unused",
            () => storyChart("header", false),
        ],
        [
            "chart-footnote-unreferenced",
            "#661: chart related from a reached glossary's footnotes sidecar, Id unused",
            () => storyChart("footnote", false),
        ],
        [
            "chart-glossary-unreferenced",
            "#661: chart related from a reached glossary document's sidecar, Id unused",
            () => storyChart("glossary", false),
        ],
        [
            "chart-unselected-fallback",
            "#661: the drawing only in an unselected mc:Fallback (selected empty w14 Choice)",
            () => fallbackChart(false),
        ],
        [
            "chart-two-relationships-no-references",
            "#661: two chart relationships to one part, neither Id used",
            () => twoRelationships(false),
        ],
        [
            "chart-equivalent-target-unreferenced",
            "#661: relationship targets CHARTS/%63hart1.xml, Id unused",
            () => equivalentTarget(false),
        ],
        ["s39a-control-minimal-end", "control", control],
    ],
    s39b: [
        ["s39b-control-minimal", "control", control],
        [
            "package-root-nested-fallback",
            "#662: Fallback holds a second wrapper whose Fallback holds Relationships",
            () => packageRoot(wrap(wrap(PLAIN))),
        ],
        ["package-root-three-nested-fallback", "#662: three nested Fallback wrappers", () => packageRoot(wrap(wrap(wrap(PLAIN))))],
        [
            "package-root-multiple-choices",
            "#662: unselected foo Choice, then a selected w14 Choice holding Relationships",
            () =>
                packageRoot(
                    `<mc:AlternateContent ${DECL}><mc:Choice Requires="foo"/><mc:Choice Requires="w14">${PLAIN}</mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                ),
        ],
        [
            "package-root-first-of-two-understood-choices",
            "#662: two w14 Choices, the first holding Relationships, the second a foreign element",
            () =>
                packageRoot(
                    `<mc:AlternateContent ${DECL}><mc:Choice Requires="w14">${PLAIN}</mc:Choice><mc:Choice Requires="w14"><foo:bad/></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                ),
        ],
        [
            "package-root-mustunderstand-w14",
            '#662: the Fallback wrapper with mc:MustUnderstand="w14"',
            () => packageRoot(replaceOnce(wrap(PLAIN), "<mc:AlternateContent ", '<mc:AlternateContent mc:MustUnderstand="w14" ')),
        ],
        [
            "package-root-ignorable-child",
            '#662: the Fallback wrapper around a Relationships with mc:Ignorable="foo" and a foo:bad child',
            () =>
                packageRoot(
                    wrap(
                        replaceOnce(
                            replaceOnce(PLAIN, "<Relationships ", '<Relationships mc:Ignorable="foo" '),
                            "</Relationships>",
                            "<foo:bad/></Relationships>",
                        ),
                    ),
                ),
        ],
        ["s39b-control-minimal-end", "control", control],
    ],
    s39c: [
        ["s39c-control-minimal", "control", control],
        ["chart-header-referenced", "#661 twin: the header's drawing names the chart", () => storyChart("header", true)],
        ["chart-footnote-referenced", "#661 twin: the glossary footnotes' drawing names the chart", () => storyChart("footnote", true)],
        ["chart-glossary-referenced", "#661 twin: the glossary document's drawing names the chart", () => storyChart("glossary", true)],
        ["chart-selected-fallback", "#661 twin: the drawing in a selected mc:Fallback (unselected foo Choice)", () => fallbackChart(true)],
        [
            "chart-two-relationships-one-reference",
            "#661 twin: two chart relationships, the drawing names rId9",
            () => twoRelationships(true),
        ],
        ["chart-equivalent-target-referenced", "#661 twin: equivalent target, the drawing names it", () => equivalentTarget(true)],
        ["s39c-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

Session 40's builder (`s40a`, `s40b`) is another standalone script, run the same way from the layer 135 worktree, with `CHUNK` naming the chunk:

```ts
// Session 40 (2026-10-25): the Word evidence #653 and #665 ask for before their fixes change a verdict or an output
// Word could see. #653: repairMissingParaIds now declares w14 on the stamped part's root and lists it in mc:Ignorable;
// s40a shows Word the repaired bytes the fix writes (taken from the real repair, not rebuilt) and release's shape, with
// xmlns:w14 on each stamped element and no Ignorable entry. #665: the file-reference walk no longer resolves a
// TargetMode="External" target as a part under strict and word-valid. Word-valid changes only for External targets
// the rels-broken blocking predicate keeps (`.rels`, `/_rels/`, `../customXml/`), so s40a/s40b show Word those, as a
// direct child and inside a selected w14 Choice, plus one a w:hyperlink names and one `file:///…pdf` reference.
// Run from the layer 135 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s40a pnpm exec tsx s40builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { NS } from "./src/lib/types";
import { validate } from "./src/scripts/office/validate";
import { DOCXSchemaValidator } from "./src/scripts/office/validators/docx";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { DOCUMENT_RELS, MCE_DECLARATIONS } from "./tests/support/relationships-markup-compatibility-specimens";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const W15 = "http://schemas.microsoft.com/office/word/2012/wordml";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const HYPERLINK = `${R}/hyperlink`;
const MAIN = "word/document.xml";
const replaceOnce = (text: string, from: string | RegExp, to: string): string => {
    const next = text.replace(from, to);
    if (next === text) throw new Error(`missing ${from}`);
    return next;
};

// tests/paraid-repair-w14-ignorable.test.ts: a main document whose root carries `rootAttributes` and whose two
// paragraphs and one table row have no ids.
const withoutParaIds = (rootAttributes: string): Record<string, string> => ({
    ...MINIMAL_PARTS,
    [MAIN]:
        `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
        `<w:document xmlns:w="${W}"${rootAttributes}><w:body>` +
        `<w:p><w:r><w:t>one</w:t></w:r></w:p>` +
        `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/></w:tblPr><w:tblGrid><w:gridCol w:w="4000"/></w:tblGrid>` +
        `<w:tr><w:tc><w:p/></w:tc></w:tr></w:tbl>` +
        `<w:sectPr><w:pgSz w:w="12240" w:h="15840"/></w:sectPr></w:body></w:document>`,
});

// The bytes repairMissingParaIds writes for `parts`, read back from the directory it repaired.
const workRoot = path.join(process.env.BUILD_DIR ?? ".", "..", "work");
const repairedParts = async (name: string, parts: Record<string, string>): Promise<Record<string, string>> => {
    const dir = path.join(workRoot, name);
    for (const [part, xml] of Object.entries(parts)) {
        mkdirSync(path.dirname(path.join(dir, part)), { recursive: true });
        writeFileSync(path.join(dir, part), xml, "utf-8");
    }
    const repairs = await new DOCXSchemaValidator({ unpackedDir: dir }).repairMissingParaIds();
    if (repairs !== 6) throw new Error(`${name}: expected 6 stamps, got ${repairs}`);
    const out: Record<string, string> = {};
    for (const entry of readdirSync(dir, { recursive: true, withFileTypes: true })) {
        if (!entry.isFile()) continue;
        const file = path.join(entry.parentPath, entry.name);
        out[path.relative(dir, file).split(path.sep).join("/")] = readFileSync(file, "utf-8");
    }
    return out;
};
const repaired = async (name: string, rootAttributes: string) => buildDocx(await repairedParts(name, withoutParaIds(rootAttributes)));

// Release's repair shape: the same stamps with xmlns:w14 on each stamped element and the root left as it was.
const releaseShape = async () => {
    const parts = await repairedParts("653-release-repair-shape", withoutParaIds(""));
    const fixed = replaceOnce(parts[MAIN]!, ` xmlns:mc="${NS.MC}" xmlns:w14="${W14}" mc:Ignorable="w14"`, "");
    const release = fixed.replace(/<w:(p|tr) w14:paraId=/g, `<w:$1 xmlns:w14="${W14}" w14:paraId=`);
    if ((release.match(/xmlns:w14=/g) ?? []).length !== 3) throw new Error("release shape: expected three stamped elements");
    return buildDocx({ ...parts, [MAIN]: release });
};

// tests/rels-external-target.integration.test.ts: the minimal package plus hyperlink relationship rId9 to `target`,
// a direct child or inside a selected w14 Choice; `referenced` adds a w:hyperlink naming rId9.
const withHyperlink = (target: string, placement: "direct" | "choice", referenced = false) => {
    const relationship = `<Relationship Id="rId9" Type="${HYPERLINK}" Target="${target}" TargetMode="External"/>`;
    const content =
        placement === "direct"
            ? relationship
            : `<mc:AlternateContent><mc:Choice Requires="w14">${relationship}</mc:Choice><mc:Fallback/></mc:AlternateContent>`;
    const rels = MINIMAL_PARTS[DOCUMENT_RELS]!;
    const parts: Record<string, string> = {
        ...MINIMAL_PARTS,
        [DOCUMENT_RELS]: replaceOnce(
            placement === "direct" ? rels : replaceOnce(rels, "<Relationships ", `<Relationships ${MCE_DECLARATIONS} `),
            "</Relationships>",
            `${content}</Relationships>`,
        ),
    };
    if (referenced) {
        parts[MAIN] = replaceOnce(
            replaceOnce(parts[MAIN]!, "<w:document ", `<w:document xmlns:r="${R}" `),
            "<w:r><w:t>Hello</w:t></w:r>",
            `<w:hyperlink r:id="rId9"><w:r><w:t>Hello</w:t></w:r></w:hyperlink>`,
        );
    }
    return buildDocx(parts);
};
const control = () => buildDocx({ ...MINIMAL_PARTS });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s40a: [
        ["s40a-control-minimal", "control", control],
        [
            "653-repaired-root-w14",
            '#653: the repair\'s output for a root with neither w14 nor mc (root gains both, mc:Ignorable="w14")',
            () => repaired("653-repaired-root-w14", ""),
        ],
        [
            "653-repaired-root-w14-w15",
            '#653: the repair\'s output for a root listing w15 (mc:Ignorable="w15 w14")',
            () => repaired("653-repaired-root-w14-w15", ` xmlns:w15="${W15}" xmlns:mc="${NS.MC}" mc:Ignorable="w15"`),
        ],
        [
            "653-repaired-compat-prefix",
            '#653: the repair\'s output for a root binding compat to the MC namespace (compat:Ignorable="w15 w14")',
            () => repaired("653-repaired-compat-prefix", ` xmlns:compat="${NS.MC}" compat:Ignorable="w15" xmlns:w15="${W15}"`),
        ],
        ["653-release-repair-shape", "#653: release's output, xmlns:w14 on each stamped element and no Ignorable entry", releaseShape],
        [
            "665-external-file-pdf-direct",
            "#665: External hyperlink file:///C:/missing.pdf, direct child, no reference",
            () => withHyperlink("file:///C:/missing.pdf", "direct"),
        ],
        [
            "665-external-file-rels-direct",
            "#665: External hyperlink file:///missing.rels, direct child, no reference",
            () => withHyperlink("file:///missing.rels", "direct"),
        ],
        ["s40a-control-minimal-end", "control", control],
    ],
    s40b: [
        ["s40b-control-minimal", "control", control],
        [
            "665-external-file-rels-choice",
            "#665: External hyperlink file:///missing.rels in a selected w14 Choice",
            () => withHyperlink("file:///missing.rels", "choice"),
        ],
        [
            "665-external-underscore-rels-direct",
            "#665: External hyperlink file:///C:/docs/_rels/missing.xml, direct child",
            () => withHyperlink("file:///C:/docs/_rels/missing.xml", "direct"),
        ],
        [
            "665-external-underscore-rels-choice",
            "#665: External hyperlink file:///C:/docs/_rels/missing.xml in a selected w14 Choice",
            () => withHyperlink("file:///C:/docs/_rels/missing.xml", "choice"),
        ],
        [
            "665-external-customxml-direct",
            "#665: External hyperlink ../customXml/missing.xml, direct child",
            () => withHyperlink("../customXml/missing.xml", "direct"),
        ],
        [
            "665-external-customxml-choice",
            "#665: External hyperlink ../customXml/missing.xml in a selected w14 Choice",
            () => withHyperlink("../customXml/missing.xml", "choice"),
        ],
        [
            "665-external-file-rels-referenced",
            "#665: External hyperlink file:///missing.rels, direct child, named by a w:hyperlink",
            () => withHyperlink("file:///missing.rels", "direct", true),
        ],
        ["s40b-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

</details>

### Session 44: 06:56Z–07:01Z on 2026-10-26, validator columns at 37a691ce

The scope questions of [#647](https://github.com/jandira-tech/docx-validate/issues/647): which relationship types make Word load a part whose own relationships part is missing. Every specimen but the controls holds session 36's bare chart (`c:externalData r:id="rId1"`, no `.rels` beside it, a chart Override) reached from `word/_rels/document.xml.rels`: `s44a` varies the image relationship and the reference, `s44b` and `s44c` the type and the folder. `chart-outside-word-mixed-reach-no-sidecar` is s37b's specimen, copied byte for byte. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 20 rows agree. The two times in Observed are the ends of the first and second runs.

| Run    | Observed             | Specimen                                                       | Chart part               | Reached by                 | Referenced by                                              | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at 37a691ce          | strict at 37a691ce                                          |
| ------ | -------------------- | -------------------------------------------------------------- | ------------------------ | -------------------------- | ---------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ------------------------------- | ----------------------------------------------------------- |
| `s44a` | 06:56:39Z, 06:59:15Z | `s44a-control-minimal`                                         | -                        | none (control)             | -                                                          | `e4dabe1c9658c28b` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-mixed-reach-no-sidecar`                    | `charts/chart1.xml`      | chart `rId9`, image `rId8` | nothing                                                    | `d9fcab69f2cdbbb8` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-image-only-reach-no-sidecar`               | `charts/chart1.xml`      | image `rId8`               | nothing                                                    | `8eb087e5355f411d` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-image-only-blip-reference-no-sidecar`      | `charts/chart1.xml`      | image `rId8`               | `a:blip r:embed="rId8"`                                    | `46943e1a314f70cc` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-mixed-reach-blip-reference-no-sidecar`     | `charts/chart1.xml`      | image `rId8`, chart `rId9` | `a:blip r:embed="rId8"`                                    | `30a66813b8b05bf6` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-mixed-reach-chart-reference-no-sidecar`    | `charts/chart1.xml`      | image `rId8`, chart `rId9` | `c:chart r:id="rId9"`                                      | `9e9562b495ce000a` | open-error  | open-error  | open-error | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44a` | 06:56:39Z, 06:59:15Z | `chart-outside-word-image-only-blip-reference-no-externaldata` | `charts/chart1.xml`      | image `rId8`               | `a:blip r:embed="rId8"`; the chart has no `c:externalData` | `5d7fa3a5a3da824c` | clean-open  | clean-open  | clean-open | valid                           | invalid: `xsd-summary`, `xsd-error`                         |
| `s44a` | 06:56:39Z, 06:59:15Z | `s44a-control-minimal-end`                                     | -                        | none (control)             | -                                                          | `e4dabe1c9658c28b` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |
| `s44b` | 06:59:51Z, 07:00:12Z | `s44b-control-minimal`                                         | -                        | none (control)             | -                                                          | `88d92a30b52cc6ef` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |
| `s44b` | 06:59:51Z, 07:00:12Z | `chart-outside-word-diagramdata-reach-no-sidecar`              | `charts/chart1.xml`      | diagramData `rId8`         | nothing                                                    | `d4968e85577d8e63` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44b` | 06:59:51Z, 07:00:12Z | `chart-outside-word-oleobject-reach-no-sidecar`                | `charts/chart1.xml`      | oleObject `rId8`           | nothing                                                    | `b9507c23854d53db` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44b` | 06:59:51Z, 07:00:12Z | `chart-outside-word-hdphoto-reach-no-sidecar`                  | `charts/chart1.xml`      | Microsoft hdphoto `rId8`   | nothing                                                    | `505ae2ea618f2910` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44b` | 06:59:51Z, 07:00:12Z | `chart-word-image-only-reach-no-sidecar`                       | `word/charts/chart1.xml` | image `rId8`               | nothing                                                    | `a38f1e7376f9ab36` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44b` | 06:59:51Z, 07:00:12Z | `chart-word-image-only-blip-reference-no-sidecar`              | `word/charts/chart1.xml` | image `rId8`               | `a:blip r:embed="rId8"`                                    | `4aa1dbb1b9180477` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44b` | 06:59:51Z, 07:00:12Z | `s44b-control-minimal-end`                                     | -                        | none (control)             | -                                                          | `88d92a30b52cc6ef` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |
| `s44c` | 07:01:09Z, 07:01:20Z | `s44c-control-minimal`                                         | -                        | none (control)             | -                                                          | `dae596edaa80e6b6` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |
| `s44c` | 07:01:09Z, 07:01:20Z | `chart-word-diagramdata-reach-no-sidecar`                      | `word/charts/chart1.xml` | diagramData `rId8`         | nothing                                                    | `879f27179e30c59c` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44c` | 07:01:09Z, 07:01:20Z | `chart-word-oleobject-reach-no-sidecar`                        | `word/charts/chart1.xml` | oleObject `rId8`           | nothing                                                    | `d25cdbd46dad561c` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44c` | 07:01:09Z, 07:01:20Z | `chart-word-hdphoto-reach-no-sidecar`                          | `word/charts/chart1.xml` | Microsoft hdphoto `rId8`   | nothing                                                    | `e1dd73af234d744c` | clean-open  | clean-open  | clean-open | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s44c` | 07:01:09Z, 07:01:20Z | `s44c-control-minimal-end`                                     | -                        | none (control)             | -                                                          | `9a327ba5c3067a64` | clean-open  | clean-open  | clean-open | valid                           | valid                                                       |

<details><summary>Raw records, session 44</summary>

```jsonl
{"run": "s44a", "pass": 1, "name": "s44a-control-minimal", "sha256": "e4dabe1c9658c28b94b19b6cbdc4fca5b812f3bae1af8aa039eabedc513dd735", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00007__wfv__s44a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "s44a-control-minimal", "sha256": "e4dabe1c9658c28b94b19b6cbdc4fca5b812f3bae1af8aa039eabedc513dd735", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00007__wfv__s44a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-mixed-reach-no-sidecar", "sha256": "d9fcab69f2cdbbb8df4017d185aad23cd7328387506cde9bb2b4a1093867e3b9", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00005__wfv__chart-outside-word-mixed-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-mixed-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-mixed-reach-no-sidecar", "sha256": "d9fcab69f2cdbbb8df4017d185aad23cd7328387506cde9bb2b4a1093867e3b9", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00005__wfv__chart-outside-word-mixed-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-mixed-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-image-only-reach-no-sidecar", "sha256": "8eb087e5355f411ded565cd06f8b1d2149f12f0271660e1c7d23f113c1bbac9f", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00002__wfv__chart-outside-word-image-only-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-image-only-reach-no-sidecar", "sha256": "8eb087e5355f411ded565cd06f8b1d2149f12f0271660e1c7d23f113c1bbac9f", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00002__wfv__chart-outside-word-image-only-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-image-only-blip-reference-no-sidecar", "sha256": "46943e1a314f70ccfb5f91ba15254a06e3307b4f7c6f07d62efb5bed40dd54e2", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00001__wfv__chart-outside-word-image-only-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-image-only-blip-reference-no-sidecar", "sha256": "46943e1a314f70ccfb5f91ba15254a06e3307b4f7c6f07d62efb5bed40dd54e2", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00001__wfv__chart-outside-word-image-only-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-mixed-reach-blip-reference-no-sidecar", "sha256": "30a66813b8b05bf69764bbdf56fcd41d71dc5cb8bdcac697d3c35cefe1be8f39", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00003__wfv__chart-outside-word-mixed-reach-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-mixed-reach-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-mixed-reach-blip-reference-no-sidecar", "sha256": "30a66813b8b05bf69764bbdf56fcd41d71dc5cb8bdcac697d3c35cefe1be8f39", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00003__wfv__chart-outside-word-mixed-reach-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-mixed-reach-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-mixed-reach-chart-reference-no-sidecar", "sha256": "9e9562b495ce000acf0387fa53486e3fe2056eedc38a52c3195030f8e239e9e4", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00004__wfv__chart-outside-word-mixed-reach-chart-reference-no-sidecar.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 02:56:30.106 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__chart-outside-word-mixed-...)'"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-mixed-reach-chart-reference-no-sidecar", "sha256": "9e9562b495ce000acf0387fa53486e3fe2056eedc38a52c3195030f8e239e9e4", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00004__wfv__chart-outside-word-mixed-reach-chart-reference-no-sidecar.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 02:59:02.248 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__chart-outside-word-mixed-...)'"]}
{"run": "s44a", "pass": 1, "name": "chart-outside-word-image-only-blip-reference-no-externaldata", "sha256": "5d7fa3a5a3da824c3736e580e9fb80555f12be170929a9c2ffb59db0b34b6cde", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00000__wfv__chart-outside-word-image-only-blip-reference-no-externaldata.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-blip-reference-no-externaldata_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "chart-outside-word-image-only-blip-reference-no-externaldata", "sha256": "5d7fa3a5a3da824c3736e580e9fb80555f12be170929a9c2ffb59db0b34b6cde", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00000__wfv__chart-outside-word-image-only-blip-reference-no-externaldata.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-image-only-blip-reference-no-externaldata_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 1, "name": "s44a-control-minimal-end", "sha256": "e4dabe1c9658c28b94b19b6cbdc4fca5b812f3bae1af8aa039eabedc513dd735", "observedAt": "2026-10-26T06:56:39+00:00", "staged": "00006__wfv__s44a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44a", "pass": 2, "name": "s44a-control-minimal-end", "sha256": "e4dabe1c9658c28b94b19b6cbdc4fca5b812f3bae1af8aa039eabedc513dd735", "observedAt": "2026-10-26T06:59:15+00:00", "staged": "00006__wfv__s44a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "s44b-control-minimal", "sha256": "88d92a30b52cc6eff10d919b78e660a484b3ed515bcf4a0b624832490eb0afdc", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00006__wfv__s44b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "s44b-control-minimal", "sha256": "88d92a30b52cc6eff10d919b78e660a484b3ed515bcf4a0b624832490eb0afdc", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00006__wfv__s44b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "chart-outside-word-diagramdata-reach-no-sidecar", "sha256": "d4968e85577d8e639434aada8639c1e514b1a641ddc0868bfeb6bc62e9032326", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00000__wfv__chart-outside-word-diagramdata-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-diagramdata-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "chart-outside-word-diagramdata-reach-no-sidecar", "sha256": "d4968e85577d8e639434aada8639c1e514b1a641ddc0868bfeb6bc62e9032326", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00000__wfv__chart-outside-word-diagramdata-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-diagramdata-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "chart-outside-word-oleobject-reach-no-sidecar", "sha256": "b9507c23854d53dbaf21462212aa4477079e61db623b2a2969c921229dc3d0c1", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00002__wfv__chart-outside-word-oleobject-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-oleobject-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "chart-outside-word-oleobject-reach-no-sidecar", "sha256": "b9507c23854d53dbaf21462212aa4477079e61db623b2a2969c921229dc3d0c1", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00002__wfv__chart-outside-word-oleobject-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-oleobject-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "chart-outside-word-hdphoto-reach-no-sidecar", "sha256": "505ae2ea618f291018de24a45347ea4ab0edf1d261a4c03d3f7fe211a3921a3a", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00001__wfv__chart-outside-word-hdphoto-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-hdphoto-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "chart-outside-word-hdphoto-reach-no-sidecar", "sha256": "505ae2ea618f291018de24a45347ea4ab0edf1d261a4c03d3f7fe211a3921a3a", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00001__wfv__chart-outside-word-hdphoto-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-hdphoto-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "chart-word-image-only-reach-no-sidecar", "sha256": "a38f1e7376f9ab36ee003aeeca2f95b315c301aff9691466d7641a13de347d6d", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00004__wfv__chart-word-image-only-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-only-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "chart-word-image-only-reach-no-sidecar", "sha256": "a38f1e7376f9ab36ee003aeeca2f95b315c301aff9691466d7641a13de347d6d", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00004__wfv__chart-word-image-only-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-only-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "chart-word-image-only-blip-reference-no-sidecar", "sha256": "4aa1dbb1b9180477ff198d54552be3e159984542d9c53e8e310d2098d01bf4f0", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00003__wfv__chart-word-image-only-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-only-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "chart-word-image-only-blip-reference-no-sidecar", "sha256": "4aa1dbb1b9180477ff198d54552be3e159984542d9c53e8e310d2098d01bf4f0", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00003__wfv__chart-word-image-only-blip-reference-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-only-blip-reference-no-sidecar_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 1, "name": "s44b-control-minimal-end", "sha256": "88d92a30b52cc6eff10d919b78e660a484b3ed515bcf4a0b624832490eb0afdc", "observedAt": "2026-10-26T06:59:51+00:00", "staged": "00005__wfv__s44b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44b", "pass": 2, "name": "s44b-control-minimal-end", "sha256": "88d92a30b52cc6eff10d919b78e660a484b3ed515bcf4a0b624832490eb0afdc", "observedAt": "2026-10-26T07:00:12+00:00", "staged": "00005__wfv__s44b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 1, "name": "s44c-control-minimal", "sha256": "dae596edaa80e6b6fa772c1cbc86158580e0cf6a5ee3122a714776c43ac1ba19", "observedAt": "2026-10-26T07:01:09+00:00", "staged": "00004__wfv__s44c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 2, "name": "s44c-control-minimal", "sha256": "dae596edaa80e6b6fa772c1cbc86158580e0cf6a5ee3122a714776c43ac1ba19", "observedAt": "2026-10-26T07:01:20+00:00", "staged": "00004__wfv__s44c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 1, "name": "chart-word-diagramdata-reach-no-sidecar", "sha256": "879f27179e30c59c7e07ee3377a7eb571a83f9ab24ff57345d023b740a72babd", "observedAt": "2026-10-26T07:01:09+00:00", "staged": "00000__wfv__chart-word-diagramdata-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-diagramdata-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 2, "name": "chart-word-diagramdata-reach-no-sidecar", "sha256": "879f27179e30c59c7e07ee3377a7eb571a83f9ab24ff57345d023b740a72babd", "observedAt": "2026-10-26T07:01:20+00:00", "staged": "00000__wfv__chart-word-diagramdata-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-diagramdata-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 1, "name": "chart-word-oleobject-reach-no-sidecar", "sha256": "d25cdbd46dad561c9f1526d47dbb5031f9dccf5e9bd46c4f2e0f1afe3c9f4f7a", "observedAt": "2026-10-26T07:01:09+00:00", "staged": "00002__wfv__chart-word-oleobject-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-oleobject-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 2, "name": "chart-word-oleobject-reach-no-sidecar", "sha256": "d25cdbd46dad561c9f1526d47dbb5031f9dccf5e9bd46c4f2e0f1afe3c9f4f7a", "observedAt": "2026-10-26T07:01:20+00:00", "staged": "00002__wfv__chart-word-oleobject-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-oleobject-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 1, "name": "chart-word-hdphoto-reach-no-sidecar", "sha256": "e1dd73af234d744c83b7c2620caef4eccc5840eb21b0a452014c3ba8e023af2b", "observedAt": "2026-10-26T07:01:09+00:00", "staged": "00001__wfv__chart-word-hdphoto-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-hdphoto-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 2, "name": "chart-word-hdphoto-reach-no-sidecar", "sha256": "e1dd73af234d744c83b7c2620caef4eccc5840eb21b0a452014c3ba8e023af2b", "observedAt": "2026-10-26T07:01:20+00:00", "staged": "00001__wfv__chart-word-hdphoto-reach-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-hdphoto-reach-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 1, "name": "s44c-control-minimal-end", "sha256": "9a327ba5c3067a640b63c8e65edcdfaac1f3a185ef51b576a87d9c6b248958f9", "observedAt": "2026-10-26T07:01:09+00:00", "staged": "00003__wfv__s44c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s44c", "pass": 2, "name": "s44c-control-minimal-end", "sha256": "9a327ba5c3067a640b63c8e65edcdfaac1f3a185ef51b576a87d9c6b248958f9", "observedAt": "2026-10-26T07:01:20+00:00", "staged": "00003__wfv__s44c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s44c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 44 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s44builder.mts`:

```ts
// Session 44 (2026-10-26): the scope questions of #647. Session 37 (s37b) saw Word open clean a chart part outside
// word/ (`charts/chart1.xml`, `c:externalData r:id="rId1"`, no sidecar) that a chart and an image relationship both
// reach and nothing references; word-valid still rejects it with `rels-missing-sidecar`, because #645 moved only a
// chart-only reach off the reach-based rule.
// s44a: the image relationship. s37b's mixed-reach specimen again, byte for byte (a second observation); the same chart reached only by an image relationship, unreferenced (question 1); an
// inline picture whose `a:blip r:embed` names that image relationship, with the image-only reach and with the mixed
// reach (question 2); the mixed reach referenced through the chart relationship (`c:chart r:id`), which session 36
// saw get the recovery offer under a chart-only reach; and a control for the blip: the same picture naming a chart part
// with no `c:externalData`, so no Id dangles.
// s44b: the other relationship types (question 3). The same unreferenced chart part reached only by a `diagramData`,
// an `oleObject` or a Microsoft `hdphoto` relationship; and the image-only reach, unreferenced and blip-referenced, of
// the chart stored under word/ (`word/charts/chart1.xml`), which word-valid judges as a Word-read part.
// s44c: the diagramData, oleObject and hdphoto reaches of s44b, unreferenced, of the chart stored under word/.
// Run from the layer 138 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s44a pnpm exec tsx s44builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

type Parts = Record<string, string>;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
const CHART_OUTSIDE = "charts/chart1.xml";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};

// Session 36's bare chart, byte for byte as s37b's mixed-reach specimen stored it, and its twin with no external data.
const chart = (externalData: boolean) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart>${externalData ? '<c:externalData r:id="rId1"/>' : ""}</c:chartSpace>`;

const relationship = (id: string, type: string, target: string) => `<Relationship Id="${id}" Type="${type}" Target="${target}"/>`;
const OFFICE = (segment: string) => `${R}/${segment}`;
const HDPHOTO = "http://schemas.microsoft.com/office/2007/relationships/hdphoto";

/** The chart part outside word/, its chart Override, and the given relationships from the main document's sidecar. */
const reachedChart = (externalData: boolean, ...relationships: string[]): Parts => ({
    ...MINIMAL_PARTS,
    [CHART_OUTSIDE]: chart(externalData),
    [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`),
    [CT]: replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `<Override PartName="/${CHART_OUTSIDE}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/></Types>`,
    ),
});
const CHART_INSIDE = "word/charts/chart1.xml";
/** The same chart stored under word/, related only by one relationship of `type` from the main document's sidecar. */
const reachedChartInside = (type: string): Parts => ({
    ...MINIMAL_PARTS,
    [CHART_INSIDE]: chart(true),
    [SIDECAR]: replaceOnce(
        MINIMAL_PARTS[SIDECAR]!,
        "</Relationships>",
        `${relationship("rId8", type, "charts/chart1.xml")}</Relationships>`,
    ),
    [CT]: replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `<Override PartName="/${CHART_INSIDE}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/></Types>`,
    ),
});
const IMAGE_REL = relationship("rId8", OFFICE("image"), `../${CHART_OUTSIDE}`);
const CHART_REL = relationship("rId9", OFFICE("chart"), `../${CHART_OUTSIDE}`);

const PICTURE_DRAWING =
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Picture 1"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr>' +
    `<a:graphic><a:graphicData uri="${PIC}"><pic:pic><pic:nvPicPr><pic:cNvPr id="0" name="Picture 1"/><pic:cNvPicPr/></pic:nvPicPr>` +
    '<pic:blipFill><a:blip r:embed="rId8"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>' +
    '<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="952500" cy="952500"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>' +
    "</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>";
// s37b's chart drawing (session 36's referenced chart).
const CHART_DRAWING =
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">' +
    '<c:chart r:id="rId9"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>';
const withDrawing = (parts: Parts, drawing: string): Parts => ({
    ...parts,
    "word/document.xml": replaceOnce(
        replaceOnce(
            MINIMAL_PARTS["word/document.xml"]!,
            "<w:document ",
            `<w:document xmlns:wp="${WP}" xmlns:a="${A}" xmlns:pic="${PIC}" xmlns:c="${C}" xmlns:r="${R}" `,
        ),
        "<w:sectPr>",
        `${drawing}<w:sectPr>`,
    ),
});
const control = () => buildDocx({ ...MINIMAL_PARTS });
const PROBES = "/Users/arthrod/temp/T/docx-validate/.scratch/word-probes";
const copyOf = (file: string, shaPrefix: string) => async (): Promise<Uint8Array> => {
    const bytes = readFileSync(path.join(PROBES, file));
    const sha = createHash("sha256").update(bytes).digest("hex");
    if (!sha.startsWith(shaPrefix)) throw new Error(`${file} changed: ${sha}`);
    return bytes;
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s44a: [
        ["s44a-control-minimal", "control", control],
        [
            "chart-outside-word-mixed-reach-no-sidecar",
            "#647 recheck: s37b's specimen, byte for byte",
            copyOf("s37b/src/chart-outside-word-mixed-reach-no-sidecar.docx", "d9fcab69f2cdbbb8"),
        ],
        [
            "chart-outside-word-image-only-reach-no-sidecar",
            "#647 q1: chart reached only by an image relationship, unreferenced",
            () => buildDocx(reachedChart(true, IMAGE_REL)),
        ],
        [
            "chart-outside-word-image-only-blip-reference-no-sidecar",
            "#647 q2: image-only reach, a:blip r:embed names it",
            () => buildDocx(withDrawing(reachedChart(true, IMAGE_REL), PICTURE_DRAWING)),
        ],
        [
            "chart-outside-word-mixed-reach-blip-reference-no-sidecar",
            "#647 q2: chart and image reach, a:blip r:embed names the image one",
            () => buildDocx(withDrawing(reachedChart(true, IMAGE_REL, CHART_REL), PICTURE_DRAWING)),
        ],
        [
            "chart-outside-word-mixed-reach-chart-reference-no-sidecar",
            "#647: chart and image reach, c:chart r:id names the chart one",
            () => buildDocx(withDrawing(reachedChart(true, IMAGE_REL, CHART_REL), CHART_DRAWING)),
        ],
        [
            "chart-outside-word-image-only-blip-reference-no-externaldata",
            "#647 control: the blip names a chart part with no dangling Id",
            () => buildDocx(withDrawing(reachedChart(false, IMAGE_REL), PICTURE_DRAWING)),
        ],
        ["s44a-control-minimal-end", "control", control],
    ],
    s44b: [
        ["s44b-control-minimal", "control", control],
        [
            "chart-outside-word-diagramdata-reach-no-sidecar",
            "#647 q3: chart reached only by a diagramData relationship, unreferenced",
            () => buildDocx(reachedChart(true, relationship("rId8", OFFICE("diagramData"), `../${CHART_OUTSIDE}`))),
        ],
        [
            "chart-outside-word-oleobject-reach-no-sidecar",
            "#647 q3: chart reached only by an oleObject relationship, unreferenced",
            () => buildDocx(reachedChart(true, relationship("rId8", OFFICE("oleObject"), `../${CHART_OUTSIDE}`))),
        ],
        [
            "chart-outside-word-hdphoto-reach-no-sidecar",
            "#647 q3: chart reached only by a Microsoft hdphoto relationship, unreferenced",
            () => buildDocx(reachedChart(true, relationship("rId8", HDPHOTO, `../${CHART_OUTSIDE}`))),
        ],
        [
            "chart-word-image-only-reach-no-sidecar",
            "#647: word/charts/chart1.xml reached only by an image relationship, unreferenced",
            () => buildDocx(reachedChartInside(OFFICE("image"))),
        ],
        [
            "chart-word-image-only-blip-reference-no-sidecar",
            "#647: word/charts/chart1.xml reached only by an image relationship, a:blip r:embed names it",
            () => buildDocx(withDrawing(reachedChartInside(OFFICE("image")), PICTURE_DRAWING)),
        ],
        ["s44b-control-minimal-end", "control", control],
    ],
    s44c: [
        ["s44c-control-minimal", "control", control],
        [
            "chart-word-diagramdata-reach-no-sidecar",
            "#647 q3: word/charts/chart1.xml reached only by a diagramData relationship, unreferenced",
            () => buildDocx(reachedChartInside(OFFICE("diagramData"))),
        ],
        [
            "chart-word-oleobject-reach-no-sidecar",
            "#647 q3: word/charts/chart1.xml reached only by an oleObject relationship, unreferenced",
            () => buildDocx(reachedChartInside(OFFICE("oleObject"))),
        ],
        [
            "chart-word-hdphoto-reach-no-sidecar",
            "#647 q3: word/charts/chart1.xml reached only by a Microsoft hdphoto relationship, unreferenced",
            () => buildDocx(reachedChartInside(HDPHOTO)),
        ],
        ["s44c-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-44 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in ("s44a", "s44b", "s44c"):
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s44/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r["file"]:<62} {r['sha256'][:16]} outcome={r['outcome']:<27} readings={','.join(r['readings'])} word-valid={r['wordValid']} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-44 parts of docs/plans/evidence/word-probes-2026-10-24.md into s44/section.md.

Reads each chunk's specimens.jsonl (validator columns at 37a691ce, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s44/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
# Where the bare chart is stored, the relationships from word/_rels/document.xml.rels that reach it, and what references one.
SHAPE = {
    "chart-outside-word-mixed-reach-no-sidecar": ("charts/chart1.xml", "chart `rId9`, image `rId8`", "nothing"),
    "chart-outside-word-image-only-reach-no-sidecar": ("charts/chart1.xml", "image `rId8`", "nothing"),
    "chart-outside-word-image-only-blip-reference-no-sidecar": ("charts/chart1.xml", "image `rId8`", '`a:blip r:embed="rId8"`'),
    "chart-outside-word-mixed-reach-blip-reference-no-sidecar": ("charts/chart1.xml", "image `rId8`, chart `rId9`", '`a:blip r:embed="rId8"`'),
    "chart-outside-word-mixed-reach-chart-reference-no-sidecar": ("charts/chart1.xml", "image `rId8`, chart `rId9`", '`c:chart r:id="rId9"`'),
    "chart-outside-word-image-only-blip-reference-no-externaldata": ("charts/chart1.xml", "image `rId8`", '`a:blip r:embed="rId8"`; the chart has no `c:externalData`'),
    "chart-outside-word-diagramdata-reach-no-sidecar": ("charts/chart1.xml", "diagramData `rId8`", "nothing"),
    "chart-outside-word-oleobject-reach-no-sidecar": ("charts/chart1.xml", "oleObject `rId8`", "nothing"),
    "chart-outside-word-hdphoto-reach-no-sidecar": ("charts/chart1.xml", "Microsoft hdphoto `rId8`", "nothing"),
    "chart-word-image-only-reach-no-sidecar": ("word/charts/chart1.xml", "image `rId8`", "nothing"),
    "chart-word-image-only-blip-reference-no-sidecar": ("word/charts/chart1.xml", "image `rId8`", '`a:blip r:embed="rId8"`'),
    "chart-word-diagramdata-reach-no-sidecar": ("word/charts/chart1.xml", "diagramData `rId8`", "nothing"),
    "chart-word-oleobject-reach-no-sidecar": ("word/charts/chart1.xml", "oleObject `rId8`", "nothing"),
    "chart-word-hdphoto-reach-no-sidecar": ("word/charts/chart1.xml", "Microsoft hdphoto `rId8`", "nothing"),
}
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s44/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw = [], []
for label in ("s44a", "s44b", "s44c"):
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        part, reach, reference = SHAPE.get(s["name"], (None, "none (control)", "-"))
        stored = "-" if part is None else f"`{part}`"
        result = results[(label, s["file"])]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {stored} | {reach} | {reference} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    "### Session 44: 06:56Z–07:01Z on 2026-10-26, validator columns at 37a691ce",
    "",
    "The scope questions of [#647](https://github.com/jandira-tech/docx-validate/issues/647): which relationship types "
    "make Word load a part whose own relationships part is missing. Every specimen but the controls holds session 36's "
    "bare chart (`c:externalData r:id=\"rId1\"`, no `.rels` beside it, a chart Override) reached from "
    "`word/_rels/document.xml.rels`: `s44a` varies the image relationship and the reference, `s44b` and `s44c` the type "
    "and the folder. `chart-outside-word-mixed-reach-no-sidecar` is s37b's specimen, copied byte for byte. Each chunk "
    "ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own "
    "Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both "
    "runs and both readings agree, and `unknown` otherwise; all 20 rows agree. The two times in Observed are the ends "
    "of the first and second runs.",
    "",
    "| Run | Observed | Specimen | Chart part | Reached by | Referenced by | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 37a691ce | strict at 37a691ce |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 44</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 44 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s44builder.mts", ROOT / "s44builder.mts", "ts"), ("compare.py", ROOT / "s44/compare.py", "python"),
                         ("section.py", ROOT / "s44/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s44/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 45: 08:05Z–08:54Z on 2026-10-26, validator columns at dbbbdc47

The questions of [#694](https://github.com/jandira-tech/docx-validate/issues/694) (two relationships of a type Word reads once), [#702](https://github.com/jandira-tech/docx-validate/issues/702) (reference shapes of a chart part with no sidecar that Word was never shown) and the cause behind [#701](https://github.com/jandira-tech/docx-validate/issues/701)'s rows. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 62 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- `s45a`–`s45b`, #694: each probe document holds a `Heading1` paragraph `MARKER`; one styles part defines `Heading1` with `w:vanish` and the other without it. Alone, each opens clean and renders as designed (pdftotext: `Hello` for the vanishing part, `Hello MARKER` for the visible one). Two `styles` relationships get the recovery offer whichever part is listed first and whichever Id it has, and so do two `officeDocument` relationships (word-valid already rejects those with `word-main-document-part`).
- `s45f`–`s45g`, #694's scope: two `styles` relationships to the same part and two `numbering` relationships also get the recovery offer; two `footnotes` relationships open clean. The doubled `settings`, `fontTable` and `webSettings` rows repeat earlier sessions' verdicts, which the existing `word-duplicate-*-relationship` rules already block.
- `s45b`–`s45d`, #702, with session 36's bare chart (`c:plotArea` with no chart type, `c:externalData r:id`, no sidecar): D1a (`dgm:relIds` names the chart's Id) gets the recovery offer, under `word/` and outside it; D1b (VML `v:imagedata o:relid`) opens clean; S1 (a picture's `a:blip r:embed` names a `diagramData` or `oleObject` relationship to the chart) opens clean, where word-valid rejects it; S2 (an External `chart` relationship with an internal-looking target, named by `c:chart r:id`) gets the recovery offer; S3 (an `image` relationship in `_rels/.rels` targeting the chart) opens clean. #701's three rows (`c:chart`, `dgm:relIds` or `o:OLEObject` naming an image relationship to the chart) get the recovery offer.
- `s45h`–`s45k`, the causes, with session 36d's clustered bar chart in place of the bare one: the bar chart with no `c:externalData` and no sidecar opens clean under `c:chart r:id` (s36d's control again), but gets the recovery offer when `dgm:relIds` names its chart relationship, so D1a is refused for the reference, not the missing sidecar. S2's refusal needs no part at all: an External `chart` relationship to `http://example.com/chart1.xml` named by `c:chart r:id` gets the same offer. An image relationship to a real PNG gets the offer when `c:chart`, `dgm:relIds` or `o:OLEObject` names it, and so does an image relationship to the bar chart under `c:chart`: #701's rows are refused for the reference's type, whatever the target.
- `s45e` asked the cause questions first, with the bare chart, eight specimens in one run. After an open error on its first specimen the driver hit AppleEvent timeouts and recovered Word four times; most rows have no dialog in the log, and the chunk never got a second run. Its rows are not recorded here; `s45h`–`s45k` re-ask them.

| Run    | Observed             | Specimen                                                 | Shape                                                                                           | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at dbbbdc47                              | strict at dbbbdc47                                                               |
| ------ | -------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------- |
| `s45a` | 08:05:36Z, 08:08:22Z | `s45a-control-minimal`                                   | control                                                                                         | `a00a1856caaae7f7` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `dup-styles-v1-vanish-first`                             | #694 V1: rId1→styles.xml (vanish) first, rId2→styles2.xml (visible)                             | `714222ecaedec663` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `dup-styles-v2-visible-first`                            | #694 V2: rId1→styles.xml (visible) first, rId2→styles2.xml (vanish)                             | `3472a73a5ca2df4d` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `dup-styles-v3-order-vs-id`                              | #694 V3: rId2→styles.xml (vanish) listed first, rId1→styles2.xml (visible) second               | `fd1e12b6128affae` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `styles-vanish-only`                                     | #694 control: one styles relationship, Heading1 vanishes                                        | `972265f3d7c6faa8` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `styles-visible-only`                                    | #694 control: one styles relationship, Heading1 visible                                         | `0a463d3d06d060fd` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45a` | 08:05:36Z, 08:08:22Z | `dup-main-m1-aaa-first`                                  | #694 M1: rId1→word/document.xml (AAA) first, rId2→word/document2.xml (BBB)                      | `88d8846ad0e48c06` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-main-document-part`                  | invalid: `word-main-document-part`                                               |
| `s45a` | 08:05:36Z, 08:08:22Z | `s45a-control-minimal-end`                               | control                                                                                         | `2409ce2bbbc8d770` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45b` | 08:10:46Z, 08:12:39Z | `s45b-control-minimal`                                   | control                                                                                         | `805efb8a22d4f352` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45b` | 08:10:46Z, 08:12:39Z | `dup-main-m2-bbb-first`                                  | #694 M2: rId1→word/document.xml (BBB) first, rId2→word/document2.xml (AAA)                      | `17be02c742b62f85` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-main-document-part`                  | invalid: `word-main-document-part`                                               |
| `s45b` | 08:10:46Z, 08:12:39Z | `dup-main-m3-order-vs-id`                                | #694 M3: rId2→word/document.xml (AAA) listed first, rId1→word/document2.xml (BBB) second        | `245b18089553766c` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-main-document-part`                  | invalid: `word-main-document-part`                                               |
| `s45b` | 08:10:46Z, 08:12:39Z | `chart-word-chart-reach-relids-reference`                | #702 D1a: chart reach, dgm:relIds r:dm names the chart Id                                       | `f6193a1344aa398a` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45b` | 08:10:46Z, 08:12:39Z | `chart-word-chart-reach-vml-relid-reference`             | #702 D1b: chart reach, v:imagedata o:relid names the chart Id                                   | `626ff10631c97887` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45b` | 08:10:46Z, 08:12:39Z | `chart-word-diagramdata-reach-blip-reference`            | #702 S1a: diagramData reach, a:blip r:embed names it                                            | `154bd618b98ef9de` | clean-open     | clean-open     | clean-open                 | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45b` | 08:10:46Z, 08:12:39Z | `chart-word-oleobject-reach-blip-reference`              | #702 S1b: oleObject reach, a:blip r:embed names it                                              | `080f436002b47b5a` | clean-open     | clean-open     | clean-open                 | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45b` | 08:10:46Z, 08:12:39Z | `s45b-control-minimal-end`                               | control                                                                                         | `805efb8a22d4f352` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45c` | 08:16:25Z, 08:19:30Z | `s45c-control-minimal`                                   | control                                                                                         | `805efb8a22d4f352` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-word-external-chart-relationship-chart-reference` | #702 S2: External chart relationship (Target charts/chart1.xml), c:chart r:id names it          | `3cec0dac5cc79b81` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-unreferenced`, `rels-missing-sidecar`, `xsd-summary`, `xsd-error` |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-word-package-image-reach`                         | #702 S3: image relationship in _rels/.rels targets word/charts/chart1.xml                       | `95cc84f92085346f` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-word-image-reach-chart-reference`                 | #701: image reach, c:chart r:id names the image Id                                              | `7aef73be039bc506` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-word-image-reach-relids-reference`                | #701: image reach, dgm:relIds r:dm names the image Id                                           | `7539ae6680306322` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-outside-word-image-reach-oleobject-reference`     | #701: chart outside word/, image reach, o:OLEObject r:id names the image Id                     | `852c1687bf00f61b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45c` | 08:16:25Z, 08:19:30Z | `chart-word-chart-reach-chart-reference`                 | control (s36d's refused shape): chart reach, c:chart r:id names it                              | `c7e293374bdf3c3b` | open-error     | open-error     | open-error                 | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45c` | 08:16:25Z, 08:19:30Z | `s45c-control-minimal-end`                               | control                                                                                         | `805efb8a22d4f352` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45d` | 08:20:17Z, 08:20:46Z | `s45d-control-minimal`                                   | control                                                                                         | `950a363196eba495` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45d` | 08:20:17Z, 08:20:46Z | `chart-outside-word-chart-reach-relids-reference`        | #702 D1a outside word/: chart reach, dgm:relIds r:dm names the chart Id                         | `156bc920f84dc52a` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45d` | 08:20:17Z, 08:20:46Z | `chart-outside-word-chart-reach-vml-relid-reference`     | #702 D1b outside word/: chart reach, v:imagedata o:relid names the chart Id                     | `070cf06cd8b488d2` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45d` | 08:20:17Z, 08:20:46Z | `chart-outside-word-diagramdata-reach-blip-reference`    | #702 S1a outside word/: diagramData reach, a:blip r:embed names it                              | `2f2502412e864336` | clean-open     | clean-open     | clean-open                 | invalid: `rels-missing-sidecar`                     | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45d` | 08:20:17Z, 08:20:46Z | `chart-word-image-reach-blip-reference`                  | control (session 44, clean): image reach, a:blip r:embed names it                               | `b46d8a7ccc93d64b` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                      |
| `s45d` | 08:20:17Z, 08:20:46Z | `s45d-control-minimal-end`                               | control                                                                                         | `950a363196eba495` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `s45f-control-minimal`                                   | control                                                                                         | `05bfe8b662c06a45` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `dup-styles-same-target`                                 | #694 scope: rId1 and rId2 both styles relationships to word/styles.xml                          | `4f7344a3f78a1d01` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `settings-single`                                        | #694 scope control: one settings relationship                                                   | `23256dbaace30840` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `settings-dup`                                           | #694 scope: two settings relationships to two parts                                             | `f3ee3fac4c121220` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`                                  |
| `s45f` | 08:39:08Z, 08:41:16Z | `fonttable-single`                                       | #694 scope control: one fontTable relationship                                                  | `6deffe96ba87bcfb` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `fonttable-dup`                                          | #694 scope: two fontTable relationships to two parts                                            | `ae4c91d14606dc40` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-font-table-relationship`   | invalid: `word-duplicate-font-table-relationship`                                |
| `s45f` | 08:39:08Z, 08:41:16Z | `numbering-dup`                                          | #694 scope: two numbering relationships to two parts                                            | `c8916291d7eedd91` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45f` | 08:39:08Z, 08:41:16Z | `s45f-control-minimal-end`                               | control                                                                                         | `05bfe8b662c06a45` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:17Z | `s45g-control-minimal`                                   | control                                                                                         | `05bfe8b662c06a45` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:17Z | `numbering-single`                                       | #694 scope control: one numbering relationship                                                  | `77e8bdd24a4fa060` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:17Z | `websettings-single`                                     | #694 scope control: one webSettings relationship                                                | `6bb7f0e5b2f3a360` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:17Z | `websettings-dup`                                        | #694 scope: two webSettings relationships to two parts                                          | `e6eac6331c70f2db` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-web-settings-relationship` | invalid: `word-duplicate-web-settings-relationship`                              |
| `s45g` | 08:42:39Z, 08:44:17Z | `footnotes-single`                                       | #694 scope control: one footnotes relationship                                                  | `6badb2ec8b60c743` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:16Z | `footnotes-dup`                                          | #694 scope: two footnotes relationships to two parts                                            | `8b97af2307353537` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45g` | 08:42:39Z, 08:44:17Z | `settings-dup-same-target`                               | #694 scope: two settings relationships to one part                                              | `0dfc82dfc1007298` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`                                  |
| `s45g` | 08:42:39Z, 08:44:17Z | `s45g-control-minimal-end`                               | control                                                                                         | `a6a90f9408c5878a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45h` | 08:45:46Z, 08:46:04Z | `s45h-control-minimal`                                   | control                                                                                         | `26c6737b23675b90` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45h` | 08:45:46Z, 08:46:04Z | `bar-noexternal-chart-reach-chart-reference`             | calibration (s36d's control again): bar chart without c:externalData, chart reach, c:chart r:id | `c825c11f1cab3b03` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45h` | 08:45:46Z, 08:46:04Z | `bar-noexternal-chart-reach-relids-reference`            | D1a cause: bar chart without c:externalData, chart reach, dgm:relIds names it                   | `30d081576f2b4ef8` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45h` | 08:45:46Z, 08:46:04Z | `s45h-control-minimal-end`                               | control                                                                                         | `26c6737b23675b90` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45i` | 08:46:56Z, 08:48:24Z | `s45i-control-minimal`                                   | control                                                                                         | `d6dd6313557ea91a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45i` | 08:46:56Z, 08:48:24Z | `bar-chart-reach-relids-reference`                       | D1a with the bar chart: c:externalData r:id with no sidecar, chart reach, dgm:relIds names it   | `a6e36d51da8c07e9` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-missing-sidecar`                                                  |
| `s45i` | 08:46:56Z, 08:48:24Z | `remote-external-chart-relationship-chart-reference`     | S2 cause: External chart relationship to http://example.com/chart1.xml, no part, c:chart r:id   | `a6bf72790a4077ca` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45i` | 08:46:56Z, 08:48:24Z | `s45i-control-minimal-end`                               | control                                                                                         | `d6dd6313557ea91a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45j` | 08:49:37Z, 08:50:47Z | `s45j-control-minimal`                                   | control                                                                                         | `d6dd6313557ea91a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45j` | 08:49:37Z, 08:50:47Z | `png-image-relationship-chart-reference`                 | #701 cause: image relationship to a real PNG, c:chart r:id names it                             | `55d09bb7fa5a5698` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45j` | 08:49:37Z, 08:50:47Z | `png-image-relationship-relids-reference`                | #701 cause: image relationship to a real PNG, dgm:relIds names it                               | `c7d2c01f39aae0d6` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45j` | 08:49:37Z, 08:50:47Z | `s45j-control-minimal-end`                               | control                                                                                         | `d6dd6313557ea91a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45k` | 08:52:25Z, 08:54:14Z | `s45k-control-minimal`                                   | control                                                                                         | `d6dd6313557ea91a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |
| `s45k` | 08:52:25Z, 08:54:14Z | `png-image-relationship-oleobject-reference`             | #701 cause: image relationship to a real PNG, o:OLEObject r:id names it                         | `5c8466e7a6b3b28e` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45k` | 08:52:25Z, 08:54:14Z | `bar-noexternal-image-reach-chart-reference`             | #701 cause: bar chart without c:externalData, image reach, c:chart r:id names it                | `135966b4c0639e00` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | valid                                                                            |
| `s45k` | 08:52:25Z, 08:54:14Z | `s45k-control-minimal-end`                               | control                                                                                         | `10e3029de8ce3858` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                            |

<details><summary>Raw records, session 45</summary>

```jsonl
{"run": "s45a", "pass": 1, "name": "s45a-control-minimal", "sha256": "a00a1856caaae7f7e958e95ecde390caea5a1c7aa48f3048564b2cdff60b9353", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00005__wfv__s45a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 2, "name": "s45a-control-minimal", "sha256": "a00a1856caaae7f7e958e95ecde390caea5a1c7aa48f3048564b2cdff60b9353", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00005__wfv__s45a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 1, "name": "dup-styles-v1-vanish-first", "sha256": "714222ecaedec663f1cbbdf0d25a5dbf28565a8ceb4e1e5bf026964e9ced880b", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00001__wfv__dup-styles-v1-vanish-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:04:23.143 Microsoft Word, Word found unreadable content in 00001__wfv__dup-styles-v1-vanish-first.docx. Do you … t? If you trust the source of this document, click Yes.", "2026-10-26 04:04:23.240 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__dup-styles-v1-vanish-firs...)'"]}
{"run": "s45a", "pass": 2, "name": "dup-styles-v1-vanish-first", "sha256": "714222ecaedec663f1cbbdf0d25a5dbf28565a8ceb4e1e5bf026964e9ced880b", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00001__wfv__dup-styles-v1-vanish-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:06:59.906 Microsoft Word, Word found unreadable content in 00001__wfv__dup-styles-v1-vanish-first.docx. Do you … t? If you trust the source of this document, click Yes.", "2026-10-26 04:07:00.592 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__dup-styles-v1-vanish-firs...)\""]}
{"run": "s45a", "pass": 1, "name": "dup-styles-v2-visible-first", "sha256": "3472a73a5ca2df4d3f8e3356f0c815a00bad738f1db911e4300aeb3287c9f55b", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00002__wfv__dup-styles-v2-visible-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:04:58.432 'Word found unreadable content in 00002__wfv__dup-styles-v2-visible-first.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s45a", "pass": 2, "name": "dup-styles-v2-visible-first", "sha256": "3472a73a5ca2df4d3f8e3356f0c815a00bad738f1db911e4300aeb3287c9f55b", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00002__wfv__dup-styles-v2-visible-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:07:43.983 Microsoft Word, Word found unreadable content in 00002__wfv__dup-styles-v2-visible-first.docx. Do yo … t? If you trust the source of this document, click Yes."]}
{"run": "s45a", "pass": 1, "name": "dup-styles-v3-order-vs-id", "sha256": "fd1e12b6128affae84e31fb443b1ada25cd7d57956e79248174ebfe95a4ef4b1", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00003__wfv__dup-styles-v3-order-vs-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:05:33.740 'Word found unreadable content in 00003__wfv__dup-styles-v3-order-vs-id.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'"]}
{"run": "s45a", "pass": 2, "name": "dup-styles-v3-order-vs-id", "sha256": "fd1e12b6128affae84e31fb443b1ada25cd7d57956e79248174ebfe95a4ef4b1", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00003__wfv__dup-styles-v3-order-vs-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:08:19.416 'Word found unreadable content in 00003__wfv__dup-styles-v3-order-vs-id.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'"]}
{"run": "s45a", "pass": 1, "name": "styles-vanish-only", "sha256": "972265f3d7c6faa831a608a13c155df55c8d11fe49844fc9874a444e18a89f68", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00006__wfv__styles-vanish-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-vanish-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 2, "name": "styles-vanish-only", "sha256": "972265f3d7c6faa831a608a13c155df55c8d11fe49844fc9874a444e18a89f68", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00006__wfv__styles-vanish-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-vanish-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 1, "name": "styles-visible-only", "sha256": "0a463d3d06d060fdf1c53fe1895509953ecd3c3a060b607e1a43cd3ca5c58c94", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00007__wfv__styles-visible-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-visible-only_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 2, "name": "styles-visible-only", "sha256": "0a463d3d06d060fdf1c53fe1895509953ecd3c3a060b607e1a43cd3ca5c58c94", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00007__wfv__styles-visible-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-visible-only_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 1, "name": "dup-main-m1-aaa-first", "sha256": "88d8846ad0e48c069944a4ea84959d0825bb94eabb6213f3f17acd53d86bb45c", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00000__wfv__dup-main-m1-aaa-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:03:38.982 'Word found unreadable content in 00000__wfv__dup-main-m1-aaa-first.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:03:39.524 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00000__wfv__dup-main-m1-aaa-first.docx)\""]}
{"run": "s45a", "pass": 2, "name": "dup-main-m1-aaa-first", "sha256": "88d8846ad0e48c069944a4ea84959d0825bb94eabb6213f3f17acd53d86bb45c", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00000__wfv__dup-main-m1-aaa-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:06:07.175 'Word found unreadable content in 00000__wfv__dup-main-m1-aaa-first.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:06:07.730 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00000__wfv__dup-main-m1-aaa-first.docx)\""]}
{"run": "s45a", "pass": 1, "name": "s45a-control-minimal-end", "sha256": "2409ce2bbbc8d770b31972222699b29d1186f8e6722db8a93d4dc71fe29adb9e", "observedAt": "2026-10-26T08:05:36+00:00", "staged": "00004__wfv__s45a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45a", "pass": 2, "name": "s45a-control-minimal-end", "sha256": "2409ce2bbbc8d770b31972222699b29d1186f8e6722db8a93d4dc71fe29adb9e", "observedAt": "2026-10-26T08:08:22+00:00", "staged": "00004__wfv__s45a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 1, "name": "s45b-control-minimal", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00007__wfv__s45b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 2, "name": "s45b-control-minimal", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00007__wfv__s45b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 1, "name": "dup-main-m2-bbb-first", "sha256": "17be02c742b62f859b7e58f4ee00c3d3dd4c4513c19d96cb86dd4d4680194c3c", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00004__wfv__dup-main-m2-bbb-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:09:56.389 \"Word found unreadable content in 00004__wfv__dup-main-m2-bbb-first.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\"", "2026-10-26 04:09:56.390 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00004__wfv__dup-main-m2-bbb-first.docx)\""]}
{"run": "s45b", "pass": 2, "name": "dup-main-m2-bbb-first", "sha256": "17be02c742b62f859b7e58f4ee00c3d3dd4c4513c19d96cb86dd4d4680194c3c", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00004__wfv__dup-main-m2-bbb-first.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:11:48.467 \"Word found unreadable content in 00004__wfv__dup-main-m2-bbb-first.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\"", "2026-10-26 04:11:48.468 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00004__wfv__dup-main-m2-bbb-first.docx)\""]}
{"run": "s45b", "pass": 1, "name": "dup-main-m3-order-vs-id", "sha256": "245b18089553766cfe9487ca065d74cb0336e28c77e3ca91ebd7061cea63fe23", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00005__wfv__dup-main-m3-order-vs-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:10:45.274 Microsoft Word, Word found unreadable content in 00005__wfv__dup-main-m3-order-vs-id.docx. Do you wa … t? If you trust the source of this document, click Yes."]}
{"run": "s45b", "pass": 2, "name": "dup-main-m3-order-vs-id", "sha256": "245b18089553766cfe9487ca065d74cb0336e28c77e3ca91ebd7061cea63fe23", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00005__wfv__dup-main-m3-order-vs-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:12:38.620 Microsoft Word, Word found unreadable content in 00005__wfv__dup-main-m3-order-vs-id.docx. Do you wa … t? If you trust the source of this document, click Yes."]}
{"run": "s45b", "pass": 1, "name": "chart-word-chart-reach-relids-reference", "sha256": "f6193a1344aa398a693f8c48c3039b6f9e62a8b4009db78b983f3d3ac078c7cc", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00000__wfv__chart-word-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:09:50.079 Microsoft Word, Word found unreadable content in 00000__wfv__chart-word-chart-reach-relids-reference … t? If you trust the source of this document, click Yes."]}
{"run": "s45b", "pass": 2, "name": "chart-word-chart-reach-relids-reference", "sha256": "f6193a1344aa398a693f8c48c3039b6f9e62a8b4009db78b983f3d3ac078c7cc", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00000__wfv__chart-word-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:11:42.514 Microsoft Word, Word found unreadable content in 00000__wfv__chart-word-chart-reach-relids-reference … t? If you trust the source of this document, click Yes."]}
{"run": "s45b", "pass": 1, "name": "chart-word-chart-reach-vml-relid-reference", "sha256": "626ff10631c97887ced8a683e032c4b3b4c8d77c47144139b0e6f5c7f2b54612", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00001__wfv__chart-word-chart-reach-vml-relid-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-chart-reach-vml-relid-reference_byword.pdf (13397 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 2, "name": "chart-word-chart-reach-vml-relid-reference", "sha256": "626ff10631c97887ced8a683e032c4b3b4c8d77c47144139b0e6f5c7f2b54612", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00001__wfv__chart-word-chart-reach-vml-relid-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-chart-reach-vml-relid-reference_byword.pdf (13397 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 1, "name": "chart-word-diagramdata-reach-blip-reference", "sha256": "154bd618b98ef9de2e0dba6378944a018ae40414beff2429ff9568f81ab20352", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00002__wfv__chart-word-diagramdata-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-diagramdata-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 2, "name": "chart-word-diagramdata-reach-blip-reference", "sha256": "154bd618b98ef9de2e0dba6378944a018ae40414beff2429ff9568f81ab20352", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00002__wfv__chart-word-diagramdata-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-diagramdata-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 1, "name": "chart-word-oleobject-reach-blip-reference", "sha256": "080f436002b47b5a805b68209759112f4d423fcf5cab0f9bc2cf88b7bf5ce48d", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00003__wfv__chart-word-oleobject-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-oleobject-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 2, "name": "chart-word-oleobject-reach-blip-reference", "sha256": "080f436002b47b5a805b68209759112f4d423fcf5cab0f9bc2cf88b7bf5ce48d", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00003__wfv__chart-word-oleobject-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-oleobject-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 1, "name": "s45b-control-minimal-end", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:10:46+00:00", "staged": "00006__wfv__s45b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45b", "pass": 2, "name": "s45b-control-minimal-end", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:12:39+00:00", "staged": "00006__wfv__s45b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 1, "name": "s45c-control-minimal", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00007__wfv__s45c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 2, "name": "s45c-control-minimal", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00007__wfv__s45c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 1, "name": "chart-word-external-chart-relationship-chart-reference", "sha256": "3cec0dac5cc79b81e438c58c695249d7e7ff37ef8b726090bc5dd76af5f3ebb9", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00002__wfv__chart-word-external-chart-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:13:21.077 'Word found unreadable content in 00002__wfv__chart-word-external-chart-relationship-chart-ref.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:13:21.906 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-word-external-chart...)\""]}
{"run": "s45c", "pass": 2, "name": "chart-word-external-chart-relationship-chart-reference", "sha256": "3cec0dac5cc79b81e438c58c695249d7e7ff37ef8b726090bc5dd76af5f3ebb9", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00002__wfv__chart-word-external-chart-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:18:15.993 'Word found unreadable content in 00002__wfv__chart-word-external-chart-relationship-chart-ref.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:18:16.533 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-word-external-chart...)\""]}
{"run": "s45c", "pass": 1, "name": "chart-word-package-image-reach", "sha256": "95cc84f92085346f85349a2497cc5cc51c7a88745d2084e2608533ba9295373a", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00005__wfv__chart-word-package-image-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-package-image-reach_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 2, "name": "chart-word-package-image-reach", "sha256": "95cc84f92085346f85349a2497cc5cc51c7a88745d2084e2608533ba9295373a", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00005__wfv__chart-word-package-image-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-package-image-reach_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 1, "name": "chart-word-image-reach-chart-reference", "sha256": "7aef73be039bc506220029a5d5fc767f777a84355196b641bd5ab3077b54775c", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00003__wfv__chart-word-image-reach-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:13:34.532 'Word found unreadable content in 00003__wfv__chart-word-image-reach-chart-reference.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:13:35.215 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__chart-word-image-reach-ch...)\""]}
{"run": "s45c", "pass": 2, "name": "chart-word-image-reach-chart-reference", "sha256": "7aef73be039bc506220029a5d5fc767f777a84355196b641bd5ab3077b54775c", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00003__wfv__chart-word-image-reach-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:18:25.803 'Word found unreadable content in 00003__wfv__chart-word-image-reach-chart-reference.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:18:26.431 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__chart-word-image-reach-ch...)\""]}
{"run": "s45c", "pass": 1, "name": "chart-word-image-reach-relids-reference", "sha256": "7539ae6680306322913c45ccfa8511c585614e69755bcef60db6f927d4c4fbaa", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00004__wfv__chart-word-image-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:14:26.406 Microsoft Word, Word found unreadable content in 00004__wfv__chart-word-image-reach-relids-reference … t? If you trust the source of this document, click Yes."]}
{"run": "s45c", "pass": 2, "name": "chart-word-image-reach-relids-reference", "sha256": "7539ae6680306322913c45ccfa8511c585614e69755bcef60db6f927d4c4fbaa", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00004__wfv__chart-word-image-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:19:16.798 'Word found unreadable content in 00004__wfv__chart-word-image-reach-relids-reference.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:19:17.351 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__chart-word-image-reach-re...)\""]}
{"run": "s45c", "pass": 1, "name": "chart-outside-word-image-reach-oleobject-reference", "sha256": "852c1687bf00f61b4d6a794b1170191d9896dc2c78b79c48be9973a08efedd02", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00000__wfv__chart-outside-word-image-reach-oleobject-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:13:12.673 'Word found unreadable content in 00000__wfv__chart-outside-word-image-reach-oleobject-referen.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:13:13.243 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-outside-word-image-...)\""]}
{"run": "s45c", "pass": 2, "name": "chart-outside-word-image-reach-oleobject-reference", "sha256": "852c1687bf00f61b4d6a794b1170191d9896dc2c78b79c48be9973a08efedd02", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00000__wfv__chart-outside-word-image-reach-oleobject-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:16:40.909 'Word found unreadable content in 00000__wfv__chart-outside-word-image-reach-oleobject-referen.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:16:41.451 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-outside-word-image-...)\""]}
{"run": "s45c", "pass": 1, "name": "chart-word-chart-reach-chart-reference", "sha256": "c7e293374bdf3c3bc4c10198d8f010c71ac432bf839f424df666ebf2368d0bc4", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00001__wfv__chart-word-chart-reach-chart-reference.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 04:13:16.869 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__chart-word-chart-reach-ch...)'"]}
{"run": "s45c", "pass": 2, "name": "chart-word-chart-reach-chart-reference", "sha256": "c7e293374bdf3c3bc4c10198d8f010c71ac432bf839f424df666ebf2368d0bc4", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00001__wfv__chart-word-chart-reach-chart-reference.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 04:17:26.896 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … y converter. (00001__wfv__chart-word-chart-reach-ch...)"]}
{"run": "s45c", "pass": 1, "name": "s45c-control-minimal-end", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:16:25+00:00", "staged": "00006__wfv__s45c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45c", "pass": 2, "name": "s45c-control-minimal-end", "sha256": "805efb8a22d4f352cf02f96f4c6a6d28c62d78151dde159d5c12ea79c2c0b272", "observedAt": "2026-10-26T08:19:30+00:00", "staged": "00006__wfv__s45c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 1, "name": "s45d-control-minimal", "sha256": "950a363196eba4958024657a4b903ba50eecde14f322faabdaa99f8fc689103a", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00005__wfv__s45d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 2, "name": "s45d-control-minimal", "sha256": "950a363196eba4958024657a4b903ba50eecde14f322faabdaa99f8fc689103a", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00005__wfv__s45d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 1, "name": "chart-outside-word-chart-reach-relids-reference", "sha256": "156bc920f84dc52a9034041f2fd291911298aa8ade3b274ea3b3b405c09681a5", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00000__wfv__chart-outside-word-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:20:03.802 'Word found unreadable content in 00000__wfv__chart-outside-word-chart-reach-relids-reference..... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:20:04.553 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-outside-word-chart-...)\""]}
{"run": "s45d", "pass": 2, "name": "chart-outside-word-chart-reach-relids-reference", "sha256": "156bc920f84dc52a9034041f2fd291911298aa8ade3b274ea3b3b405c09681a5", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00000__wfv__chart-outside-word-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:20:34.448 'Word found unreadable content in 00000__wfv__chart-outside-word-chart-reach-relids-reference..... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:20:35.002 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-outside-word-chart-...)\""]}
{"run": "s45d", "pass": 1, "name": "chart-outside-word-chart-reach-vml-relid-reference", "sha256": "070cf06cd8b488d2bded2ffd7211201ba1a1ed20e338c64156189fa96e0f2199", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00001__wfv__chart-outside-word-chart-reach-vml-relid-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-chart-reach-vml-relid-reference_byword.pdf (13397 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 2, "name": "chart-outside-word-chart-reach-vml-relid-reference", "sha256": "070cf06cd8b488d2bded2ffd7211201ba1a1ed20e338c64156189fa96e0f2199", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00001__wfv__chart-outside-word-chart-reach-vml-relid-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-chart-reach-vml-relid-reference_byword.pdf (13397 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 1, "name": "chart-outside-word-diagramdata-reach-blip-reference", "sha256": "2f2502412e864336c3d1f5a0dfb794ed1c9baf15d331419ad61e2f8342f5f110", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00002__wfv__chart-outside-word-diagramdata-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-diagramdata-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 2, "name": "chart-outside-word-diagramdata-reach-blip-reference", "sha256": "2f2502412e864336c3d1f5a0dfb794ed1c9baf15d331419ad61e2f8342f5f110", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00002__wfv__chart-outside-word-diagramdata-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-outside-word-diagramdata-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 1, "name": "chart-word-image-reach-blip-reference", "sha256": "b46d8a7ccc93d64b799c229063b0303f7d0233afef26dc63420c471a29922cf8", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00003__wfv__chart-word-image-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 2, "name": "chart-word-image-reach-blip-reference", "sha256": "b46d8a7ccc93d64b799c229063b0303f7d0233afef26dc63420c471a29922cf8", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00003__wfv__chart-word-image-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-word-image-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 1, "name": "s45d-control-minimal-end", "sha256": "950a363196eba4958024657a4b903ba50eecde14f322faabdaa99f8fc689103a", "observedAt": "2026-10-26T08:20:17+00:00", "staged": "00004__wfv__s45d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45d", "pass": 2, "name": "s45d-control-minimal-end", "sha256": "950a363196eba4958024657a4b903ba50eecde14f322faabdaa99f8fc689103a", "observedAt": "2026-10-26T08:20:46+00:00", "staged": "00004__wfv__s45d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 1, "name": "s45f-control-minimal", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00005__wfv__s45f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 2, "name": "s45f-control-minimal", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00005__wfv__s45f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 1, "name": "dup-styles-same-target", "sha256": "4f7344a3f78a1d01ed3bf94a844218dff1b3af4f1e67f531992935ba629195c6", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00000__wfv__dup-styles-same-target.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:37:54.126 'Word found unreadable content in 00000__wfv__dup-styles-same-target.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:37:55.160 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00000__wfv__dup-styles-same-target.docx)\""]}
{"run": "s45f", "pass": 2, "name": "dup-styles-same-target", "sha256": "4f7344a3f78a1d01ed3bf94a844218dff1b3af4f1e67f531992935ba629195c6", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00000__wfv__dup-styles-same-target.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:39:40.920 \"Word found unreadable content in 00000__wfv__dup-styles-same-target.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.\""]}
{"run": "s45f", "pass": 1, "name": "settings-single", "sha256": "23256dbaace308404eecd484ed6361a91e10ab46ddff398c820e8e3feea12e33", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00007__wfv__settings-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 2, "name": "settings-single", "sha256": "23256dbaace308404eecd484ed6361a91e10ab46ddff398c820e8e3feea12e33", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00007__wfv__settings-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 1, "name": "settings-dup", "sha256": "f3ee3fac4c121220ce26a1b7b5adccd76c3bf6c36da35cdc494f99e690762ca2", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00006__wfv__settings-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:39:08.314 \"Word found unreadable content in 00006__wfv__settings-dup.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.\""]}
{"run": "s45f", "pass": 2, "name": "settings-dup", "sha256": "f3ee3fac4c121220ce26a1b7b5adccd76c3bf6c36da35cdc494f99e690762ca2", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00006__wfv__settings-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:41:15.644 \"Word found unreadable content in 00006__wfv__settings-dup.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.\""]}
{"run": "s45f", "pass": 1, "name": "fonttable-single", "sha256": "6deffe96ba87bcfb297c866cc96bb8f0f1ab4fda395b7c5ce0390a7481d4637d", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00002__wfv__fonttable-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF fonttable-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 2, "name": "fonttable-single", "sha256": "6deffe96ba87bcfb297c866cc96bb8f0f1ab4fda395b7c5ce0390a7481d4637d", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00002__wfv__fonttable-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF fonttable-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 1, "name": "fonttable-dup", "sha256": "ae4c91d14606dc4029b26e334f6bf34d24ce6fb61d488c95d9166552063bff59", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00001__wfv__fonttable-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:38:41.354 Microsoft Word, Word found unreadable content in 00001__wfv__fonttable-dup.docx. Do you want to reco … t? If you trust the source of this document, click Yes.", "2026-10-26 04:38:41.416 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis …  Recovery converter.\\n(00001__wfv__fonttable-dup.docx)'"]}
{"run": "s45f", "pass": 2, "name": "fonttable-dup", "sha256": "ae4c91d14606dc4029b26e334f6bf34d24ce6fb61d488c95d9166552063bff59", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00001__wfv__fonttable-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:40:37.171 Microsoft Word, Word found unreadable content in 00001__wfv__fonttable-dup.docx. Do you want to reco … t? If you trust the source of this document, click Yes."]}
{"run": "s45f", "pass": 1, "name": "numbering-dup", "sha256": "c8916291d7eedd9163084660376314ac3f917b7547c48853f82649e3593735ef", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00003__wfv__numbering-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:38:47.485 \"Word found unreadable content in 00003__wfv__numbering-dup.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.\"", "2026-10-26 04:38:47.486 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … t Recovery converter. (00003__wfv__numbering-dup.docx)\""]}
{"run": "s45f", "pass": 2, "name": "numbering-dup", "sha256": "c8916291d7eedd9163084660376314ac3f917b7547c48853f82649e3593735ef", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00003__wfv__numbering-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:40:45.613 \"Word found unreadable content in 00003__wfv__numbering-dup.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.\"", "2026-10-26 04:40:45.614 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … t Recovery converter. (00003__wfv__numbering-dup.docx)\""]}
{"run": "s45f", "pass": 1, "name": "s45f-control-minimal-end", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:39:08+00:00", "staged": "00004__wfv__s45f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45f", "pass": 2, "name": "s45f-control-minimal-end", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:41:16+00:00", "staged": "00004__wfv__s45f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "s45g-control-minimal", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00004__wfv__s45g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "s45g-control-minimal", "sha256": "05bfe8b662c06a457d8a4ddb3141a6624aab3457b3d051fda6ceb1562d7b5561", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00004__wfv__s45g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "numbering-single", "sha256": "77e8bdd24a4fa0608318fb7a467c3245719b71cc6f0f59ad42d0502450af0887", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00002__wfv__numbering-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "numbering-single", "sha256": "77e8bdd24a4fa0608318fb7a467c3245719b71cc6f0f59ad42d0502450af0887", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00002__wfv__numbering-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "websettings-single", "sha256": "6bb7f0e5b2f3a3608b3acca7e993aee4f25530fa02170c2501c065bc656ec59c", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00007__wfv__websettings-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF websettings-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "websettings-single", "sha256": "6bb7f0e5b2f3a3608b3acca7e993aee4f25530fa02170c2501c065bc656ec59c", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00007__wfv__websettings-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF websettings-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "websettings-dup", "sha256": "e6eac6331c70f2dbe725c88c307ab4ed2eabaabbb1c5878f42e7d50b21964915", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00006__wfv__websettings-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:42:30.508 Microsoft Word, Word found unreadable content in 00006__wfv__websettings-dup.docx. Do you want to re … t? If you trust the source of this document, click Yes.", "2026-10-26 04:42:39.483 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00006__wfv__websettings-dup.docx)\""]}
{"run": "s45g", "pass": 2, "name": "websettings-dup", "sha256": "e6eac6331c70f2dbe725c88c307ab4ed2eabaabbb1c5878f42e7d50b21964915", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00006__wfv__websettings-dup.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:44:15.530 'Word found unreadable content in 00006__wfv__websettings-dup.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:44:16.491 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00006__wfv__websettings-dup.docx)\""]}
{"run": "s45g", "pass": 1, "name": "footnotes-single", "sha256": "6badb2ec8b60c743a0bbf9b042d9e5fe62190391daa3db0ae5e776f92c71b0ab", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00001__wfv__footnotes-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "footnotes-single", "sha256": "6badb2ec8b60c743a0bbf9b042d9e5fe62190391daa3db0ae5e776f92c71b0ab", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00001__wfv__footnotes-single.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-single_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "footnotes-dup", "sha256": "8b97af2307353537a60b6c243c6ecd0cf8aaab83410ff0621824b02f4980fea4", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00000__wfv__footnotes-dup.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-dup_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "footnotes-dup", "sha256": "8b97af2307353537a60b6c243c6ecd0cf8aaab83410ff0621824b02f4980fea4", "observedAt": "2026-10-26T08:44:16+00:00", "staged": "00000__wfv__footnotes-dup.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-dup_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 1, "name": "settings-dup-same-target", "sha256": "0dfc82dfc1007298c1120c2fbb9f6c9e6cf02666c01d4ca6beb5e232f38014e6", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00005__wfv__settings-dup-same-target.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:41:40.692 \"Word found unreadable content in 00005__wfv__settings-dup-same-target.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s45g", "pass": 2, "name": "settings-dup-same-target", "sha256": "0dfc82dfc1007298c1120c2fbb9f6c9e6cf02666c01d4ca6beb5e232f38014e6", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00005__wfv__settings-dup-same-target.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:43:45.058 Microsoft Word, Word found unreadable content in 00005__wfv__settings-dup-same-target.docx. Do you w … t? If you trust the source of this document, click Yes."]}
{"run": "s45g", "pass": 1, "name": "s45g-control-minimal-end", "sha256": "a6a90f9408c5878ab20ddbaa2360a591ad4545151256290eb60a1aeb1bc1fcd8", "observedAt": "2026-10-26T08:42:39+00:00", "staged": "00003__wfv__s45g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45g", "pass": 2, "name": "s45g-control-minimal-end", "sha256": "a6a90f9408c5878ab20ddbaa2360a591ad4545151256290eb60a1aeb1bc1fcd8", "observedAt": "2026-10-26T08:44:17+00:00", "staged": "00003__wfv__s45g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 1, "name": "s45h-control-minimal", "sha256": "26c6737b23675b90b7837e6f2d78f89fc555f8b3f534300b700e524dcf8b38b6", "observedAt": "2026-10-26T08:45:46+00:00", "staged": "00003__wfv__s45h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 2, "name": "s45h-control-minimal", "sha256": "26c6737b23675b90b7837e6f2d78f89fc555f8b3f534300b700e524dcf8b38b6", "observedAt": "2026-10-26T08:46:04+00:00", "staged": "00003__wfv__s45h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 1, "name": "bar-noexternal-chart-reach-chart-reference", "sha256": "c825c11f1cab3b03d37dcd41d40a2d85d5dde352ce8f0d54219583f50bfb1598", "observedAt": "2026-10-26T08:45:46+00:00", "staged": "00000__wfv__bar-noexternal-chart-reach-chart-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-noexternal-chart-reach-chart-reference_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 2, "name": "bar-noexternal-chart-reach-chart-reference", "sha256": "c825c11f1cab3b03d37dcd41d40a2d85d5dde352ce8f0d54219583f50bfb1598", "observedAt": "2026-10-26T08:46:04+00:00", "staged": "00000__wfv__bar-noexternal-chart-reach-chart-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-noexternal-chart-reach-chart-reference_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 1, "name": "bar-noexternal-chart-reach-relids-reference", "sha256": "30d081576f2b4ef892a06aef8131bad63d861a5c2a4f22f486037f1a817116ab", "observedAt": "2026-10-26T08:45:46+00:00", "staged": "00001__wfv__bar-noexternal-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:45:44.352 'Word found unreadable content in 00001__wfv__bar-noexternal-chart-reach-relids-reference.docx. Do y … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:45:45.083 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__bar-noexternal-chart-reac...)\""]}
{"run": "s45h", "pass": 2, "name": "bar-noexternal-chart-reach-relids-reference", "sha256": "30d081576f2b4ef892a06aef8131bad63d861a5c2a4f22f486037f1a817116ab", "observedAt": "2026-10-26T08:46:04+00:00", "staged": "00001__wfv__bar-noexternal-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:46:02.940 'Word found unreadable content in 00001__wfv__bar-noexternal-chart-reach-relids-reference.docx. Do y … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:46:03.546 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__bar-noexternal-chart-reac...)\""]}
{"run": "s45h", "pass": 1, "name": "s45h-control-minimal-end", "sha256": "26c6737b23675b90b7837e6f2d78f89fc555f8b3f534300b700e524dcf8b38b6", "observedAt": "2026-10-26T08:45:46+00:00", "staged": "00002__wfv__s45h-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45h-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45h", "pass": 2, "name": "s45h-control-minimal-end", "sha256": "26c6737b23675b90b7837e6f2d78f89fc555f8b3f534300b700e524dcf8b38b6", "observedAt": "2026-10-26T08:46:04+00:00", "staged": "00002__wfv__s45h-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45h-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45i", "pass": 1, "name": "s45i-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:46:56+00:00", "staged": "00003__wfv__s45i-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45i-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45i", "pass": 2, "name": "s45i-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:48:24+00:00", "staged": "00003__wfv__s45i-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45i-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45i", "pass": 1, "name": "bar-chart-reach-relids-reference", "sha256": "a6e36d51da8c07e9ac82c966e53cce609283d4cdcc3e0907a5e531491467a747", "observedAt": "2026-10-26T08:46:56+00:00", "staged": "00000__wfv__bar-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:46:21.382 'Word found unreadable content in 00000__wfv__bar-chart-reach-relids-reference.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:46:21.941 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__bar-chart-reach-relids-re...)\""]}
{"run": "s45i", "pass": 2, "name": "bar-chart-reach-relids-reference", "sha256": "a6e36d51da8c07e9ac82c966e53cce609283d4cdcc3e0907a5e531491467a747", "observedAt": "2026-10-26T08:48:24+00:00", "staged": "00000__wfv__bar-chart-reach-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:47:13.581 'Word found unreadable content in 00000__wfv__bar-chart-reach-relids-reference.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:47:14.167 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__bar-chart-reach-relids-re...)\""]}
{"run": "s45i", "pass": 1, "name": "remote-external-chart-relationship-chart-reference", "sha256": "a6bf72790a4077ca5cf041ef51218b74b09bb2426ca6b6b334d68d3d23c832ca", "observedAt": "2026-10-26T08:46:56+00:00", "staged": "00001__wfv__remote-external-chart-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:46:25.616 'Word found unreadable content in 00001__wfv__remote-external-chart-relationship-chart-referen.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:46:26.262 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__remote-external-chart-rel...)\""]}
{"run": "s45i", "pass": 2, "name": "remote-external-chart-relationship-chart-reference", "sha256": "a6bf72790a4077ca5cf041ef51218b74b09bb2426ca6b6b334d68d3d23c832ca", "observedAt": "2026-10-26T08:48:24+00:00", "staged": "00001__wfv__remote-external-chart-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:48:03.932 Microsoft Word, Word found unreadable content in 00001__wfv__remote-external-chart-relationship-char … t? If you trust the source of this document, click Yes.", "2026-10-26 04:48:24.399 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__remote-external-chart-rel...)\""]}
{"run": "s45i", "pass": 1, "name": "s45i-control-minimal-end", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:46:56+00:00", "staged": "00002__wfv__s45i-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45i-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45i", "pass": 2, "name": "s45i-control-minimal-end", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:48:24+00:00", "staged": "00002__wfv__s45i-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45i-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45j", "pass": 1, "name": "s45j-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:49:37+00:00", "staged": "00003__wfv__s45j-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45j-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45j", "pass": 2, "name": "s45j-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:50:47+00:00", "staged": "00003__wfv__s45j-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45j-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45j", "pass": 1, "name": "png-image-relationship-chart-reference", "sha256": "55d09bb7fa5a56989326917f646dde964b16a08842bc1b4d23e85f2160b9a37f", "observedAt": "2026-10-26T08:49:37+00:00", "staged": "00000__wfv__png-image-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:48:42.716 'Word found unreadable content in 00000__wfv__png-image-relationship-chart-reference.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:48:43.252 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__png-image-relationship-ch...)\""]}
{"run": "s45j", "pass": 2, "name": "png-image-relationship-chart-reference", "sha256": "55d09bb7fa5a56989326917f646dde964b16a08842bc1b4d23e85f2160b9a37f", "observedAt": "2026-10-26T08:50:47+00:00", "staged": "00000__wfv__png-image-relationship-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:50:00.533 'Word found unreadable content in 00000__wfv__png-image-relationship-chart-reference.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:50:01.122 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__png-image-relationship-ch...)\""]}
{"run": "s45j", "pass": 1, "name": "png-image-relationship-relids-reference", "sha256": "c7d2c01f39aae0d64c2c32aa8bfb33a92b9a7894ac4cc00282820972990ee3f0", "observedAt": "2026-10-26T08:49:37+00:00", "staged": "00001__wfv__png-image-relationship-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:49:35.462 Microsoft Word, Word found unreadable content in 00001__wfv__png-image-relationship-relids-reference … t? If you trust the source of this document, click Yes."]}
{"run": "s45j", "pass": 2, "name": "png-image-relationship-relids-reference", "sha256": "c7d2c01f39aae0d64c2c32aa8bfb33a92b9a7894ac4cc00282820972990ee3f0", "observedAt": "2026-10-26T08:50:47+00:00", "staged": "00001__wfv__png-image-relationship-relids-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:50:46.200 Microsoft Word, Word found unreadable content in 00001__wfv__png-image-relationship-relids-reference … t? If you trust the source of this document, click Yes.", "2026-10-26 04:50:46.333 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__png-image-relationship-re...)'"]}
{"run": "s45j", "pass": 1, "name": "s45j-control-minimal-end", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:49:37+00:00", "staged": "00002__wfv__s45j-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45j-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45j", "pass": 2, "name": "s45j-control-minimal-end", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:50:47+00:00", "staged": "00002__wfv__s45j-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45j-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45k", "pass": 1, "name": "s45k-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:52:25+00:00", "staged": "00003__wfv__s45k-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45k-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45k", "pass": 2, "name": "s45k-control-minimal", "sha256": "d6dd6313557ea91a986257e950b3f07d607e732f9063e53fc99ca0f587b04579", "observedAt": "2026-10-26T08:54:14+00:00", "staged": "00003__wfv__s45k-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45k-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45k", "pass": 1, "name": "png-image-relationship-oleobject-reference", "sha256": "5c8466e7a6b3b28ed4ae524c3a57dc1e513b63c44ce3d32da80420e8f1c5261c", "observedAt": "2026-10-26T08:52:25+00:00", "staged": "00001__wfv__png-image-relationship-oleobject-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:52:24.415 'Word found unreadable content in 00001__wfv__png-image-relationship-oleobject-reference.docx. Do yo … ? If you trust the source of this document, click Yes.'"]}
{"run": "s45k", "pass": 2, "name": "png-image-relationship-oleobject-reference", "sha256": "5c8466e7a6b3b28ed4ae524c3a57dc1e513b63c44ce3d32da80420e8f1c5261c", "observedAt": "2026-10-26T08:54:14+00:00", "staged": "00001__wfv__png-image-relationship-oleobject-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:54:13.236 'Word found unreadable content in 00001__wfv__png-image-relationship-oleobject-reference.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-26 04:54:13.779 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__png-image-relationship-ol...)\""]}
{"run": "s45k", "pass": 1, "name": "bar-noexternal-image-reach-chart-reference", "sha256": "135966b4c0639e00763e791317233b9c451b6aaa0ab184a934681aa70c1f22ef", "observedAt": "2026-10-26T08:52:25+00:00", "staged": "00000__wfv__bar-noexternal-image-reach-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:51:48.960 Microsoft Word, Word found unreadable content in 00000__wfv__bar-noexternal-image-reach-chart-refere … t? If you trust the source of this document, click Yes."]}
{"run": "s45k", "pass": 2, "name": "bar-noexternal-image-reach-chart-reference", "sha256": "135966b4c0639e00763e791317233b9c451b6aaa0ab184a934681aa70c1f22ef", "observedAt": "2026-10-26T08:54:14+00:00", "staged": "00000__wfv__bar-noexternal-image-reach-chart-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 04:53:24.983 Microsoft Word, Word found unreadable content in 00000__wfv__bar-noexternal-image-reach-chart-refere … t? If you trust the source of this document, click Yes.", "2026-10-26 04:53:25.671 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__bar-noexternal-image-reac...)\""]}
{"run": "s45k", "pass": 1, "name": "s45k-control-minimal-end", "sha256": "10e3029de8ce385833e98b4f7f90cc711da166cb2b9f8e020a035c8784dcb963", "observedAt": "2026-10-26T08:52:25+00:00", "staged": "00002__wfv__s45k-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45k-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s45k", "pass": 2, "name": "s45k-control-minimal-end", "sha256": "10e3029de8ce385833e98b4f7f90cc711da166cb2b9f8e020a035c8784dcb963", "observedAt": "2026-10-26T08:54:14+00:00", "staged": "00002__wfv__s45k-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s45k-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 45 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s45builder.mts`:

```ts
// Session 45 (2026-10-26): #694 (two relationships of a single-instance type) and #702/#701 (reference shapes of a
// part with no sidecar that Word was never shown).
// s45a: two `styles` relationships from the main document's sidecar. The main document holds a `Heading1` paragraph
// `MARKER` after the usual `Hello`; one candidate styles part defines `Heading1` with `w:vanish`, the other without,
// so the PDF text shows which part Word applied (vanish hides MARKER). V1: rId1→styles.xml (vanish) listed first,
// rId2→styles2.xml (visible). V2: the same order with the contents swapped. V3: rId2→styles.xml (vanish) listed first,
// rId1→styles2.xml (visible) second, so document order and Id order disagree. Controls: each styles part alone. M1:
// two `officeDocument` relationships in `_rels/.rels`, rId1→word/document.xml (`AAA`) listed first, rId2→
// word/document2.xml (`BBB`).
// s45b: M2 (M1 with the main documents' texts swapped), M3 (rId2→word/document.xml listed first, rId1→document2.xml
// second); #702 D1 (a chart Id named by `dgm:relIds r:dm`, and by VML `v:imagedata o:relid`) and S1 (a diagramData or
// oleObject Id named by a picture's `a:blip r:embed`), the chart stored under word/.
// s45c: #702 S2 (an External chart relationship with an internal-looking target named by `c:chart r:id`) and S3 (an
// image relationship in `_rels/.rels` targeting the chart); #701's rows (an image Id named by `c:chart r:id`, by
// `dgm:relIds r:dm`, and outside word/ by `o:OLEObject r:id`); a control of the refused s36d shape.
// s45d: D1 and S1 with the chart outside word/, and session 44's clean blip control under word/.
// s45e: cause controls for D1a, S2 and #701's rows. s45f, s45g: which other single-instance types Word refuses doubled.
// s45h-k: s45e again in chunks of four, with session 36d's bar chart (see the comment above barChart).
// Run from the layer 142 worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s45a pnpm exec tsx s45builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

type Parts = Record<string, string>;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
const DGM = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
const O = "urn:schemas-microsoft-com:office:office";
const V = "urn:schemas-microsoft-com:vml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN = "word/document.xml";
const STYLES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
const MAIN_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
const CHART_CT = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, type: string, target: string, external = false) =>
    `<Relationship Id="${id}" Type="${type}" Target="${target}"${external ? ' TargetMode="External"' : ""}/>`;
const OFFICE = (segment: string) => `${R}/${segment}`;
const relsPart = (...relationships: string[]) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationships.join("")}</Relationships>`;
const withOverrides = (...overrides: Array<[string, string]>) =>
    replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

// ---- #694: styles
const heading1 = (vanish: boolean) =>
    `<w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><w:basedOn w:val="Normal"/>${vanish ? "<w:rPr><w:vanish/></w:rPr>" : ""}</w:style>`;
const stylesWith = (vanish: boolean) => replaceOnce(MINIMAL_PARTS["word/styles.xml"]!, "</w:styles>", `${heading1(vanish)}</w:styles>`);
const MARKER_DOCUMENT = replaceOnce(
    MINIMAL_PARTS[MAIN]!,
    "<w:sectPr>",
    '<w:p w14:paraId="00000003" w14:textId="00000003"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>MARKER</w:t></w:r></w:p><w:sectPr>',
);
/** `rels` lists [Id, target] in document order; `contents` maps each styles part name to whether its Heading1 vanishes. */
const stylesSpecimen = (rels: Array<[string, string]>, contents: Record<string, boolean>): Parts => ({
    ...Object.fromEntries(Object.entries(MINIMAL_PARTS).filter(([name]) => name !== "word/styles.xml")),
    [MAIN]: MARKER_DOCUMENT,
    [SIDECAR]: relsPart(...rels.map(([id, target]) => relationship(id, OFFICE("styles"), target))),
    ...Object.fromEntries(Object.entries(contents).map(([name, vanish]) => [`word/${name}`, stylesWith(vanish)])),
    [CT]: withOverrides(
        ...Object.keys(contents)
            .filter((name) => name !== "styles.xml")
            .map((name): [string, string] => [`word/${name}`, STYLES_CT]),
    ),
});

// ---- #694: two main documents
const mainSaying = (text: string) => replaceOnce(MINIMAL_PARTS[MAIN]!, "<w:t>Hello</w:t>", `<w:t>${text}</w:t>`);
/** `rels` lists [Id, target] of `_rels/.rels` in document order; `texts` maps each main part to its text. */
const twoMains = (rels: Array<[string, string]>, texts: Record<string, string>): Parts => ({
    ...MINIMAL_PARTS,
    "_rels/.rels": relsPart(...rels.map(([id, target]) => relationship(id, OFFICE("officeDocument"), target))),
    ...Object.fromEntries(Object.entries(texts).map(([part, text]) => [part, mainSaying(text)])),
    "word/_rels/document2.xml.rels": MINIMAL_PARTS[SIDECAR]!,
    [CT]: withOverrides(["word/document2.xml", MAIN_CT]),
});

// ---- #702 / #701: the bare chart with no sidecar
const CHART_INSIDE = "word/charts/chart1.xml";
const CHART_OUTSIDE = "charts/chart1.xml";
const BARE_CHART = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart><c:externalData r:id="rId1"/></c:chartSpace>`;
const targetOf = (part: string) => (part === CHART_INSIDE ? "charts/chart1.xml" : `../${part}`);
const reached = (part: string, ...relationships: string[]): Parts => ({
    ...MINIMAL_PARTS,
    [part]: BARE_CHART,
    [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`),
    [CT]: withOverrides([part, CHART_CT]),
});
const PICTURE_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Picture 1"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr>' +
    `<a:graphic><a:graphicData uri="${PIC}"><pic:pic><pic:nvPicPr><pic:cNvPr id="0" name="Picture 1"/><pic:cNvPicPr/></pic:nvPicPr>` +
    `<pic:blipFill><a:blip r:embed="${id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>` +
    '<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="952500" cy="952500"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>' +
    "</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>";
const CHART_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart r:id="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const DIAGRAM_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Diagram 1"/><a:graphic><a:graphicData uri="${DGM}">` +
    `<dgm:relIds xmlns:dgm="${DGM}" r:dm="${id}" r:lo="${id}" r:qs="${id}" r:cs="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const VML_IMAGEDATA = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:pict>' +
    `<v:shape xmlns:v="${V}" xmlns:o="${O}" id="s1" style="width:10pt;height:10pt"><v:imagedata o:relid="${id}"/></v:shape></w:pict></w:r></w:p>`;
const OLE_OBJECT = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:object>' +
    `<o:OLEObject xmlns:o="${O}" Type="Embed" ProgID="Package" ShapeID="_x0000_i1025" DrawAspect="Icon" ObjectID="_1" r:id="${id}"/></w:object></w:r></w:p>`;
const withDrawing = (parts: Parts, drawing: string): Parts => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            MINIMAL_PARTS[MAIN]!,
            "<w:document ",
            `<w:document xmlns:wp="${WP}" xmlns:a="${A}" xmlns:pic="${PIC}" xmlns:c="${C}" xmlns:r="${R}" `,
        ),
        "<w:sectPr>",
        `${drawing}<w:sectPr>`,
    ),
});
const typed = (part: string, id: string, segment: string, external = false) =>
    relationship(id, OFFICE(segment), external ? "charts/chart1.xml" : targetOf(part), external);
const control = () => buildDocx({ ...MINIMAL_PARTS });

// ---- session 45 follow-ups: cause controls for s45b-d, and the scope of #694's refusal
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "base64"),
);
const CHART_NO_EXTERNAL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart></c:chartSpace>`;
/** The minimal package plus `parts`, with `relationships` appended to the main document's sidecar. */
const extended = (
    parts: Record<string, string | Uint8Array>,
    relationships: string[],
    overrides: Array<[string, string]>,
    pngDefault = false,
) => ({
    ...MINIMAL_PARTS,
    ...parts,
    [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`),
    [CT]: replaceOnce(
        withOverrides(...overrides),
        '<Default Extension="rels"',
        `${pngDefault ? '<Default Extension="png" ContentType="image/png"/>' : ""}<Default Extension="rels"`,
    ),
});
const withDrawingAny = (parts: Record<string, string | Uint8Array>, drawing: string) => withDrawing(parts as Parts, drawing);
const pngReached = () => extended({ "word/media/image1.png": PNG }, [relationship("rId8", OFFICE("image"), "media/image1.png")], [], true);
const SINGLETONS: Record<string, { root: string; ct: string }> = {
    settings: { root: `<w:settings xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" },
    fontTable: { root: `<w:fonts xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" },
    numbering: {
        root: `<w:numbering xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
    },
    webSettings: {
        root: `<w:webSettings xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
    },
    footnotes: {
        root: `<w:footnotes xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
    },
};
/** One relationship of `segment` per name in `names`, each to its own part `word/<name>`, all holding the same minimal root. */
const singletonSpecimen = (segment: string, names: string[]) => {
    const { root, ct } = SINGLETONS[segment]!;
    const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n${root}`;
    return extended(
        Object.fromEntries(names.map((name) => [`word/${name}`, xml])),
        names.map((name, index) => relationship(`rId${index + 2}`, OFFICE(segment), name)),
        names.map((name): [string, string] => [`word/${name}`, ct]),
    );
};

// ---- s45h-k: s45e again in small chunks, with session 36d's real clustered bar chart in place of the bare plotArea
// (s45e's first run got an open error for the bare chart with no c:externalData under c:chart, so the bare chart's
// content, not only its missing sidecar, may be what Word refuses once something makes it load the chart).
const BAR_PLOT_AREA =
    '<c:plotArea><c:layout/><c:barChart><c:barDir val="col"/><c:grouping val="clustered"/><c:ser><c:idx val="0"/><c:order val="0"/>' +
    '<c:val><c:numLit><c:ptCount val="1"/><c:pt idx="0"><c:v>1</c:v></c:pt></c:numLit></c:val></c:ser><c:axId val="1"/><c:axId val="2"/></c:barChart>' +
    '<c:catAx><c:axId val="1"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="b"/><c:crossAx val="2"/></c:catAx>' +
    '<c:valAx><c:axId val="2"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="l"/><c:crossAx val="1"/></c:valAx></c:plotArea>';
const barChart = (externalData: boolean) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:a="${A}" xmlns:r="${R}"><c:chart>${BAR_PLOT_AREA}</c:chart>${externalData ? '<c:externalData r:id="rId1"/>' : ""}</c:chartSpace>`;
/** The bar chart at word/charts/chart1.xml (no sidecar), reached from the main document's sidecar as `rId` of `segment`. */
const barReached = (externalData: boolean, id: string, segment: string) =>
    extended(
        { [CHART_INSIDE]: barChart(externalData) },
        [relationship(id, OFFICE(segment), "charts/chart1.xml")],
        [[CHART_INSIDE, CHART_CT]],
    );

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s45a: [
        ["s45a-control-minimal", "control", control],
        [
            "dup-styles-v1-vanish-first",
            "#694 V1: rId1→styles.xml (vanish) first, rId2→styles2.xml (visible)",
            () =>
                buildDocx(
                    stylesSpecimen(
                        [
                            ["rId1", "styles.xml"],
                            ["rId2", "styles2.xml"],
                        ],
                        { "styles.xml": true, "styles2.xml": false },
                    ),
                ),
        ],
        [
            "dup-styles-v2-visible-first",
            "#694 V2: rId1→styles.xml (visible) first, rId2→styles2.xml (vanish)",
            () =>
                buildDocx(
                    stylesSpecimen(
                        [
                            ["rId1", "styles.xml"],
                            ["rId2", "styles2.xml"],
                        ],
                        { "styles.xml": false, "styles2.xml": true },
                    ),
                ),
        ],
        [
            "dup-styles-v3-order-vs-id",
            "#694 V3: rId2→styles.xml (vanish) listed first, rId1→styles2.xml (visible) second",
            () =>
                buildDocx(
                    stylesSpecimen(
                        [
                            ["rId2", "styles.xml"],
                            ["rId1", "styles2.xml"],
                        ],
                        { "styles.xml": true, "styles2.xml": false },
                    ),
                ),
        ],
        [
            "styles-vanish-only",
            "#694 control: one styles relationship, Heading1 vanishes",
            () => buildDocx(stylesSpecimen([["rId1", "styles.xml"]], { "styles.xml": true })),
        ],
        [
            "styles-visible-only",
            "#694 control: one styles relationship, Heading1 visible",
            () => buildDocx(stylesSpecimen([["rId1", "styles.xml"]], { "styles.xml": false })),
        ],
        [
            "dup-main-m1-aaa-first",
            "#694 M1: rId1→word/document.xml (AAA) first, rId2→word/document2.xml (BBB)",
            () =>
                buildDocx(
                    twoMains(
                        [
                            ["rId1", "word/document.xml"],
                            ["rId2", "word/document2.xml"],
                        ],
                        { "word/document.xml": "AAA", "word/document2.xml": "BBB" },
                    ),
                ),
        ],
        ["s45a-control-minimal-end", "control", control],
    ],
    s45b: [
        ["s45b-control-minimal", "control", control],
        [
            "dup-main-m2-bbb-first",
            "#694 M2: rId1→word/document.xml (BBB) first, rId2→word/document2.xml (AAA)",
            () =>
                buildDocx(
                    twoMains(
                        [
                            ["rId1", "word/document.xml"],
                            ["rId2", "word/document2.xml"],
                        ],
                        { "word/document.xml": "BBB", "word/document2.xml": "AAA" },
                    ),
                ),
        ],
        [
            "dup-main-m3-order-vs-id",
            "#694 M3: rId2→word/document.xml (AAA) listed first, rId1→word/document2.xml (BBB) second",
            () =>
                buildDocx(
                    twoMains(
                        [
                            ["rId2", "word/document.xml"],
                            ["rId1", "word/document2.xml"],
                        ],
                        { "word/document.xml": "AAA", "word/document2.xml": "BBB" },
                    ),
                ),
        ],
        [
            "chart-word-chart-reach-relids-reference",
            "#702 D1a: chart reach, dgm:relIds r:dm names the chart Id",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId9", "chart")), DIAGRAM_DRAWING("rId9"))),
        ],
        [
            "chart-word-chart-reach-vml-relid-reference",
            "#702 D1b: chart reach, v:imagedata o:relid names the chart Id",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId9", "chart")), VML_IMAGEDATA("rId9"))),
        ],
        [
            "chart-word-diagramdata-reach-blip-reference",
            "#702 S1a: diagramData reach, a:blip r:embed names it",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId8", "diagramData")), PICTURE_DRAWING("rId8"))),
        ],
        [
            "chart-word-oleobject-reach-blip-reference",
            "#702 S1b: oleObject reach, a:blip r:embed names it",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId8", "oleObject")), PICTURE_DRAWING("rId8"))),
        ],
        ["s45b-control-minimal-end", "control", control],
    ],
    s45c: [
        ["s45c-control-minimal", "control", control],
        [
            "chart-word-external-chart-relationship-chart-reference",
            "#702 S2: External chart relationship (Target charts/chart1.xml), c:chart r:id names it",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId9", "chart", true)), CHART_DRAWING("rId9"))),
        ],
        [
            "chart-word-package-image-reach",
            "#702 S3: image relationship in _rels/.rels targets word/charts/chart1.xml",
            async () => {
                const parts = reached(CHART_INSIDE);
                return buildDocx({
                    ...parts,
                    "_rels/.rels": replaceOnce(
                        MINIMAL_PARTS["_rels/.rels"]!,
                        "</Relationships>",
                        `${relationship("rId2", OFFICE("image"), CHART_INSIDE)}</Relationships>`,
                    ),
                });
            },
        ],
        [
            "chart-word-image-reach-chart-reference",
            "#701: image reach, c:chart r:id names the image Id",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId8", "image")), CHART_DRAWING("rId8"))),
        ],
        [
            "chart-word-image-reach-relids-reference",
            "#701: image reach, dgm:relIds r:dm names the image Id",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId8", "image")), DIAGRAM_DRAWING("rId8"))),
        ],
        [
            "chart-outside-word-image-reach-oleobject-reference",
            "#701: chart outside word/, image reach, o:OLEObject r:id names the image Id",
            () => buildDocx(withDrawing(reached(CHART_OUTSIDE, typed(CHART_OUTSIDE, "rId8", "image")), OLE_OBJECT("rId8"))),
        ],
        [
            "chart-word-chart-reach-chart-reference",
            "control (s36d's refused shape): chart reach, c:chart r:id names it",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId9", "chart")), CHART_DRAWING("rId9"))),
        ],
        ["s45c-control-minimal-end", "control", control],
    ],
    s45d: [
        ["s45d-control-minimal", "control", control],
        [
            "chart-outside-word-chart-reach-relids-reference",
            "#702 D1a outside word/: chart reach, dgm:relIds r:dm names the chart Id",
            () => buildDocx(withDrawing(reached(CHART_OUTSIDE, typed(CHART_OUTSIDE, "rId9", "chart")), DIAGRAM_DRAWING("rId9"))),
        ],
        [
            "chart-outside-word-chart-reach-vml-relid-reference",
            "#702 D1b outside word/: chart reach, v:imagedata o:relid names the chart Id",
            () => buildDocx(withDrawing(reached(CHART_OUTSIDE, typed(CHART_OUTSIDE, "rId9", "chart")), VML_IMAGEDATA("rId9"))),
        ],
        [
            "chart-outside-word-diagramdata-reach-blip-reference",
            "#702 S1a outside word/: diagramData reach, a:blip r:embed names it",
            () => buildDocx(withDrawing(reached(CHART_OUTSIDE, typed(CHART_OUTSIDE, "rId8", "diagramData")), PICTURE_DRAWING("rId8"))),
        ],
        [
            "chart-word-image-reach-blip-reference",
            "control (session 44, clean): image reach, a:blip r:embed names it",
            () => buildDocx(withDrawing(reached(CHART_INSIDE, typed(CHART_INSIDE, "rId8", "image")), PICTURE_DRAWING("rId8"))),
        ],
        ["s45d-control-minimal-end", "control", control],
    ],
    s45e: [
        ["s45e-control-minimal", "control", control],
        [
            "chart-word-no-externaldata-chart-reference",
            "calibration: chart reach to a chart with no externalData (no sidecar needed), c:chart r:id",
            () =>
                buildDocx(
                    withDrawingAny(
                        extended(
                            { [CHART_INSIDE]: CHART_NO_EXTERNAL },
                            [relationship("rId9", OFFICE("chart"), "charts/chart1.xml")],
                            [[CHART_INSIDE, CHART_CT]],
                        ),
                        CHART_DRAWING("rId9"),
                    ),
                ),
        ],
        [
            "chart-word-no-externaldata-relids-reference",
            "D1a cause: dgm:relIds names the Id of a chart with no externalData",
            () =>
                buildDocx(
                    withDrawingAny(
                        extended(
                            { [CHART_INSIDE]: CHART_NO_EXTERNAL },
                            [relationship("rId9", OFFICE("chart"), "charts/chart1.xml")],
                            [[CHART_INSIDE, CHART_CT]],
                        ),
                        DIAGRAM_DRAWING("rId9"),
                    ),
                ),
        ],
        [
            "remote-external-chart-relationship-chart-reference",
            "S2 cause: External chart relationship to http://example.com/chart1.xml, no part, c:chart r:id",
            () =>
                buildDocx(
                    withDrawingAny(
                        extended({}, [relationship("rId9", OFFICE("chart"), "http://example.com/chart1.xml", true)], []),
                        CHART_DRAWING("rId9"),
                    ),
                ),
        ],
        [
            "png-image-relationship-chart-reference",
            "#701 cause: image relationship to a real PNG, c:chart r:id names it",
            () => buildDocx(withDrawingAny(pngReached(), CHART_DRAWING("rId8"))),
        ],
        [
            "png-image-relationship-relids-reference",
            "#701 cause: image relationship to a real PNG, dgm:relIds names it",
            () => buildDocx(withDrawingAny(pngReached(), DIAGRAM_DRAWING("rId8"))),
        ],
        [
            "png-image-relationship-oleobject-reference",
            "#701 cause: image relationship to a real PNG, o:OLEObject r:id names it",
            () => buildDocx(withDrawingAny(pngReached(), OLE_OBJECT("rId8"))),
        ],
        ["s45e-control-minimal-end", "control", control],
    ],
    s45f: [
        ["s45f-control-minimal", "control", control],
        [
            "dup-styles-same-target",
            "#694 scope: rId1 and rId2 both styles relationships to word/styles.xml",
            () =>
                buildDocx({
                    ...MINIMAL_PARTS,
                    [SIDECAR]: relsPart(
                        relationship("rId1", OFFICE("styles"), "styles.xml"),
                        relationship("rId2", OFFICE("styles"), "styles.xml"),
                    ),
                }),
        ],
        [
            "settings-single",
            "#694 scope control: one settings relationship",
            () => buildDocx(singletonSpecimen("settings", ["settings.xml"])),
        ],
        [
            "settings-dup",
            "#694 scope: two settings relationships to two parts",
            () => buildDocx(singletonSpecimen("settings", ["settings.xml", "settings2.xml"])),
        ],
        [
            "fonttable-single",
            "#694 scope control: one fontTable relationship",
            () => buildDocx(singletonSpecimen("fontTable", ["fontTable.xml"])),
        ],
        [
            "fonttable-dup",
            "#694 scope: two fontTable relationships to two parts",
            () => buildDocx(singletonSpecimen("fontTable", ["fontTable.xml", "fontTable2.xml"])),
        ],
        [
            "numbering-dup",
            "#694 scope: two numbering relationships to two parts",
            () => buildDocx(singletonSpecimen("numbering", ["numbering.xml", "numbering2.xml"])),
        ],
        ["s45f-control-minimal-end", "control", control],
    ],
    s45g: [
        ["s45g-control-minimal", "control", control],
        [
            "numbering-single",
            "#694 scope control: one numbering relationship",
            () => buildDocx(singletonSpecimen("numbering", ["numbering.xml"])),
        ],
        [
            "websettings-single",
            "#694 scope control: one webSettings relationship",
            () => buildDocx(singletonSpecimen("webSettings", ["webSettings.xml"])),
        ],
        [
            "websettings-dup",
            "#694 scope: two webSettings relationships to two parts",
            () => buildDocx(singletonSpecimen("webSettings", ["webSettings.xml", "webSettings2.xml"])),
        ],
        [
            "footnotes-single",
            "#694 scope control: one footnotes relationship",
            () => buildDocx(singletonSpecimen("footnotes", ["footnotes.xml"])),
        ],
        [
            "footnotes-dup",
            "#694 scope: two footnotes relationships to two parts",
            () => buildDocx(singletonSpecimen("footnotes", ["footnotes.xml", "footnotes2.xml"])),
        ],
        [
            "settings-dup-same-target",
            "#694 scope: two settings relationships to one part",
            () =>
                buildDocx(
                    extended(
                        { "word/settings.xml": `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n${SINGLETONS.settings!.root}` },
                        [
                            relationship("rId2", OFFICE("settings"), "settings.xml"),
                            relationship("rId3", OFFICE("settings"), "settings.xml"),
                        ],
                        [["word/settings.xml", SINGLETONS.settings!.ct]],
                    ),
                ),
        ],
        ["s45g-control-minimal-end", "control", control],
    ],
    s45h: [
        ["s45h-control-minimal", "control", control],
        [
            "bar-noexternal-chart-reach-chart-reference",
            "calibration (s36d's control again): bar chart without c:externalData, chart reach, c:chart r:id",
            () => buildDocx(withDrawingAny(barReached(false, "rId9", "chart"), CHART_DRAWING("rId9"))),
        ],
        [
            "bar-noexternal-chart-reach-relids-reference",
            "D1a cause: bar chart without c:externalData, chart reach, dgm:relIds names it",
            () => buildDocx(withDrawingAny(barReached(false, "rId9", "chart"), DIAGRAM_DRAWING("rId9"))),
        ],
        ["s45h-control-minimal-end", "control", control],
    ],
    s45i: [
        ["s45i-control-minimal", "control", control],
        [
            "bar-chart-reach-relids-reference",
            "D1a with the bar chart: c:externalData r:id with no sidecar, chart reach, dgm:relIds names it",
            () => buildDocx(withDrawingAny(barReached(true, "rId9", "chart"), DIAGRAM_DRAWING("rId9"))),
        ],
        [
            "remote-external-chart-relationship-chart-reference",
            "S2 cause: External chart relationship to http://example.com/chart1.xml, no part, c:chart r:id",
            () =>
                buildDocx(
                    withDrawingAny(
                        extended({}, [relationship("rId9", OFFICE("chart"), "http://example.com/chart1.xml", true)], []),
                        CHART_DRAWING("rId9"),
                    ),
                ),
        ],
        ["s45i-control-minimal-end", "control", control],
    ],
    s45j: [
        ["s45j-control-minimal", "control", control],
        [
            "png-image-relationship-chart-reference",
            "#701 cause: image relationship to a real PNG, c:chart r:id names it",
            () => buildDocx(withDrawingAny(pngReached(), CHART_DRAWING("rId8"))),
        ],
        [
            "png-image-relationship-relids-reference",
            "#701 cause: image relationship to a real PNG, dgm:relIds names it",
            () => buildDocx(withDrawingAny(pngReached(), DIAGRAM_DRAWING("rId8"))),
        ],
        ["s45j-control-minimal-end", "control", control],
    ],
    s45k: [
        ["s45k-control-minimal", "control", control],
        [
            "png-image-relationship-oleobject-reference",
            "#701 cause: image relationship to a real PNG, o:OLEObject r:id names it",
            () => buildDocx(withDrawingAny(pngReached(), OLE_OBJECT("rId8"))),
        ],
        [
            "bar-noexternal-image-reach-chart-reference",
            "#701 cause: bar chart without c:externalData, image reach, c:chart r:id names it",
            () => buildDocx(withDrawingAny(barReached(false, "rId8", "image"), CHART_DRAWING("rId8"))),
        ],
        ["s45k-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-45 chunks: log verdicts, table verdicts, validator verdicts, hashes.

s45e is left out: its first run stalled (AppleEvent timeouts after an open error), most rows have no evidence, and it
never got a second run; s45h-s45k re-ask its questions in chunks of four.
"""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s45a", "s45b", "s45c", "s45d", "s45f", "s45g", "s45h", "s45i", "s45j", "s45k")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s45/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-45 parts of docs/plans/evidence/word-probes-2026-10-24.md into s45/section.md.

Reads each chunk's specimens.jsonl (validator columns at dbbbdc47, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s45/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s45a", "s45b", "s45c", "s45d", "s45f", "s45g", "s45h", "s45i", "s45j", "s45k")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s45/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw = [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    "### Session 45: 08:05Z–08:54Z on 2026-10-26, validator columns at dbbbdc47",
    "",
    "The questions of [#694](https://github.com/jandira-tech/docx-validate/issues/694) (two relationships of a type Word "
    "reads once), [#702](https://github.com/jandira-tech/docx-validate/issues/702) (reference shapes of a chart part with "
    "no sidecar that Word was never shown) and the cause behind [#701](https://github.com/jandira-tech/docx-validate/issues/701)'s "
    "rows. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: "
    "from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when "
    "both runs and both readings agree, and `unknown` otherwise; all 62 rows agree. The two times in Observed are the ends "
    "of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- `s45a`–`s45b`, #694: each probe document holds a `Heading1` paragraph `MARKER`; one styles part defines `Heading1` "
    "with `w:vanish` and the other without it. Alone, each opens clean and renders as designed (pdftotext: `Hello` for the "
    "vanishing part, `Hello MARKER` for the visible one). Two `styles` relationships get the recovery offer whichever part "
    "is listed first and whichever Id it has, and so do two `officeDocument` relationships (word-valid already rejects those "
    "with `word-main-document-part`).",
    "- `s45f`–`s45g`, #694's scope: two `styles` relationships to the same part and two `numbering` relationships also get "
    "the recovery offer; two `footnotes` relationships open clean. The doubled `settings`, `fontTable` and `webSettings` "
    "rows repeat earlier sessions' verdicts, which the existing `word-duplicate-*-relationship` rules already block.",
    "- `s45b`–`s45d`, #702, with session 36's bare chart (`c:plotArea` with no chart type, `c:externalData r:id`, no "
    "sidecar): D1a (`dgm:relIds` names the chart's Id) gets the recovery offer, under `word/` and outside it; D1b (VML "
    "`v:imagedata o:relid`) opens clean; S1 (a picture's `a:blip r:embed` names a `diagramData` or `oleObject` "
    "relationship to the chart) opens clean, where word-valid rejects it; S2 (an External `chart` relationship with an "
    "internal-looking target, named by `c:chart r:id`) gets the recovery offer; S3 (an `image` relationship in "
    "`_rels/.rels` targeting the chart) opens clean. #701's three rows (`c:chart`, `dgm:relIds` or `o:OLEObject` naming an "
    "image relationship to the chart) get the recovery offer.",
    "- `s45h`–`s45k`, the causes, with session 36d's clustered bar chart in place of the bare one: the bar chart with no "
    "`c:externalData` and no sidecar opens clean under `c:chart r:id` (s36d's control again), but gets the recovery offer "
    "when `dgm:relIds` names its chart relationship, so D1a is refused for the reference, not the missing sidecar. S2's "
    "refusal needs no part at all: an External `chart` relationship to `http://example.com/chart1.xml` named by `c:chart "
    "r:id` gets the same offer. An image relationship to a real PNG gets the offer when `c:chart`, `dgm:relIds` or "
    "`o:OLEObject` names it, and so does an image relationship to the bar chart under `c:chart`: #701's rows are refused "
    "for the reference's type, whatever the target.",
    "- `s45e` asked the cause questions first, with the bare chart, eight specimens in one run. After an open error on its "
    "first specimen the driver hit AppleEvent timeouts and recovered Word four times; most rows have no dialog in the log, "
    "and the chunk never got a second run. Its rows are not recorded here; `s45h`–`s45k` re-ask them.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at dbbbdc47 | strict at dbbbdc47 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 45</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 45 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s45builder.mts", ROOT / "s45builder.mts", "ts"), ("compare.py", ROOT / "s45/compare.py", "python"),
                         ("section.py", ROOT / "s45/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s45/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 46: 09:17Z–09:27Z on 2026-10-26, validator columns at f2717ba3

The shapes [#705](https://github.com/jandira-tech/docx-validate/issues/705), [#706](https://github.com/jandira-tech/docx-validate/issues/706) and [#707](https://github.com/jandira-tech/docx-validate/issues/707) left unobserved. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 30 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- `s46a`–`s46c`, #705, on `tests/fixtures/working/word-clean-strict01.docx` (an ISO Strict document Word opened clean on 2026-10-23, with a SmartArt, a chart, an embedded Excel object and an EMF picture), one attribute of `word/document.xml` changed per specimen; the fixture re-zipped unchanged opens clean. `dgm:relIds r:dm` naming the image relationship or an Id no relationship has gets the recovery offer; `r:lo`, `r:qs` or `r:cs` naming the image relationship, and `r:lo` naming the chart relationship, open clean (the part keeps its cached `diagramDrawing`). `c:chart r:id` naming the `diagramData` or the `package` relationship, or an Id no relationship has, gets the recovery offer. `o:OLEObject r:id` in the selected `mc:Choice` naming the image or the chart relationship, or an Id no relationship has, gets the recovery offer; the fixture's own `package` relationship opens clean. Word-valid passes every refused row.
- `s46d`, #706, with session 36d's bar chart (`c:externalData r:id`, no sidecar) reached by an `image` relationship: a VML picture (`v:imagedata r:id`) or a linked picture (`a:blip r:link`) naming it opens clean, as the `a:blip r:embed` control does. Word-valid rejects the first two with `rels-missing-sidecar` (#701's extension).
- `s46e`, #707: the main document's `styles` relationship naming `word/styles.bin` gets the recovery offer when the part holds non-XML bytes or styles XML typed `application/octet-stream`, and opens clean when the same XML is typed as styles. Word-valid passes all three.

| Run    | Observed             | Specimen                            | Shape                                                                                            | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f2717ba3          | strict at f2717ba3                                                                          |
| ------ | -------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------- |
| `s46a` | 09:17:30Z, 09:20:34Z | `s46a-control-minimal`              | control                                                                                          | `5224f33011a11106` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46a` | 09:17:30Z, 09:20:34Z | `strict01-rebuilt`                  | calibration: word-clean-strict01.docx re-zipped unchanged                                        | `0c1bd7bcada6b436` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46a` | 09:17:30Z, 09:20:34Z | `strict01-relids-dm-image`          | #705: SmartArt dgm:relIds r:dm names the EMF image relationship rId18                            | `2638fbbaba3b3af4` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46a` | 09:17:30Z, 09:20:34Z | `strict01-relids-lo-image`          | #705: SmartArt dgm:relIds r:lo names the EMF image relationship rId18                            | `ff5809f1c6c7c65e` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46a` | 09:17:30Z, 09:20:34Z | `strict01-relids-qs-image`          | #705: SmartArt dgm:relIds r:qs names the EMF image relationship rId18                            | `ab0e7387df0ef42e` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46a` | 09:17:30Z, 09:20:34Z | `strict01-relids-cs-image`          | #705: SmartArt dgm:relIds r:cs names the EMF image relationship rId18                            | `d34388cd64f9a31f` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46a` | 09:17:30Z, 09:20:34Z | `s46a-control-minimal-end`          | control                                                                                          | `20280914ae374d78` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46b` | 09:19:08Z, 09:20:59Z | `s46b-control-minimal`              | control                                                                                          | `419d9468e4a06e19` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46b` | 09:19:08Z, 09:20:59Z | `strict01-relids-lo-chart`          | #705: SmartArt dgm:relIds r:lo names the chart relationship rId8                                 | `69db2624180221cd` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46b` | 09:19:08Z, 09:20:59Z | `strict01-chart-names-diagramdata`  | #705: c:chart r:id names the diagramData relationship rId35                                      | `25ad45cfa8da1245` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46b` | 09:19:08Z, 09:20:59Z | `strict01-chart-names-dangling`     | #705: c:chart r:id names rId999, which no relationship has                                       | `d6b56daa77e8c9f7` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46b` | 09:19:08Z, 09:20:59Z | `strict01-oleobject-names-image`    | #705: o:OLEObject r:id (selected mc:Choice) names the EMF image relationship rId18               | `6a9a819004265492` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46b` | 09:19:08Z, 09:20:59Z | `s46b-control-minimal-end`          | control                                                                                          | `6285cc0181da338c` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46c` | 09:19:37Z, 09:21:52Z | `s46c-control-minimal`              | control                                                                                          | `e345bd1fbcd8ff0d` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46c` | 09:19:37Z, 09:21:52Z | `strict01-oleobject-names-chart`    | #705: o:OLEObject r:id names the chart relationship rId8                                         | `a6cd1dba57a2001d` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46c` | 09:19:37Z, 09:21:52Z | `strict01-oleobject-names-dangling` | #705: o:OLEObject r:id names rId999, which no relationship has                                   | `c08cc69adac2650c` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46c` | 09:19:37Z, 09:21:52Z | `strict01-relids-dm-dangling`       | #705: SmartArt dgm:relIds r:dm names rId999, which no relationship has                           | `fd5fc14d519d3a9d` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46c` | 09:19:37Z, 09:21:52Z | `strict01-chart-names-package`      | #705: c:chart r:id names the package (embedded workbook) relationship rId19                      | `09ddf88b7734f73b` | repair-warning | repair-warning | unreadable-content-warning | valid                           | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s46c` | 09:19:37Z, 09:21:52Z | `s46c-control-minimal-end`          | control                                                                                          | `b85a32b43261b0cb` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46d` | 09:19:49Z, 09:22:06Z | `s46d-control-minimal`              | control                                                                                          | `b85a32b43261b0cb` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46d` | 09:19:49Z, 09:22:06Z | `bar-image-reach-vml-imagedata-rid` | #706 shape 2: bar chart with c:externalData, no sidecar, image reach, v:imagedata r:id names it  | `d6e6a13beec866a9` | clean-open     | clean-open     | clean-open                 | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                             |
| `s46d` | 09:19:49Z, 09:22:06Z | `bar-image-reach-blip-link`         | #706 shape 3: bar chart with c:externalData, no sidecar, image reach, a:blip r:link names it     | `9619415386768af7` | clean-open     | clean-open     | clean-open                 | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                             |
| `s46d` | 09:19:49Z, 09:22:06Z | `bar-image-reach-blip-embed`        | control (session 44's clean shape, bar chart): image reach, a:blip r:embed names it              | `622d66a70a9583d3` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`                                                             |
| `s46d` | 09:19:49Z, 09:22:06Z | `s46d-control-minimal-end`          | control                                                                                          | `b85a32b43261b0cb` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `s46e-control-minimal`              | control                                                                                          | `b85a32b43261b0cb` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `styles-bin-not-xml`                | #707: styles relationship names word/styles.bin holding non-XML bytes (application/octet-stream) | `96fcc419c89e1bad` | repair-warning | repair-warning | unreadable-content-warning | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `styles-bin-xml-octet-stream`       | #707: word/styles.bin holds styles XML (Heading1 visible), typed application/octet-stream        | `a9cec79ea237e1c9` | repair-warning | repair-warning | unreadable-content-warning | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `styles-bin-xml-styles-type`        | #707 control: word/styles.bin holds styles XML (Heading1 visible), typed as styles               | `f584ed6d48614fe0` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `styles-visible-only`               | control (session 45, clean): one styles relationship to word/styles.xml, Heading1 visible        | `f555b59f96a8abee` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |
| `s46e` | 09:20:13Z, 09:27:06Z | `s46e-control-minimal-end`          | control                                                                                          | `16a83807f8f1a5cd` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                                       |

<details><summary>Raw records, session 46</summary>

```jsonl
{"run": "s46a", "pass": 1, "name": "s46a-control-minimal", "sha256": "5224f33011a111069dad21fec333cd6563918872297e1e90f76110e22561ee76", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00001__wfv__s46a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "s46a-control-minimal", "sha256": "5224f33011a111069dad21fec333cd6563918872297e1e90f76110e22561ee76", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00001__wfv__s46a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 1, "name": "strict01-rebuilt", "sha256": "0c1bd7bcada6b436100f1746d1eef78bc46bce4fb92d64dc47642faaeb4fbd41", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00002__wfv__strict01-rebuilt.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-rebuilt_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "strict01-rebuilt", "sha256": "0c1bd7bcada6b436100f1746d1eef78bc46bce4fb92d64dc47642faaeb4fbd41", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00002__wfv__strict01-rebuilt.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-rebuilt_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 1, "name": "strict01-relids-dm-image", "sha256": "2638fbbaba3b3af4d223a62c93591f2e759f80c443ea7f1cbe702220fd3c86e1", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00004__wfv__strict01-relids-dm-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:17:28.609 \"Word found unreadable content in 00004__wfv__strict01-relids-dm-image.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s46a", "pass": 2, "name": "strict01-relids-dm-image", "sha256": "2638fbbaba3b3af4d223a62c93591f2e759f80c443ea7f1cbe702220fd3c86e1", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00004__wfv__strict01-relids-dm-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:31.780 'Word found unreadable content in 00004__wfv__strict01-relids-dm-image.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:32.367 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-relids-dm-image....)\""]}
{"run": "s46a", "pass": 1, "name": "strict01-relids-lo-image", "sha256": "ff5809f1c6c7c65ea420f1841613d6c1800edca62e3bdcb919c573fa0bb00610", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00005__wfv__strict01-relids-lo-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-lo-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "strict01-relids-lo-image", "sha256": "ff5809f1c6c7c65ea420f1841613d6c1800edca62e3bdcb919c573fa0bb00610", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00005__wfv__strict01-relids-lo-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-lo-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 1, "name": "strict01-relids-qs-image", "sha256": "ab0e7387df0ef42ea06e1c4f1ed3afdf4dae9ac712947d7f1e59e3f806a91790", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00006__wfv__strict01-relids-qs-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-qs-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "strict01-relids-qs-image", "sha256": "ab0e7387df0ef42ea06e1c4f1ed3afdf4dae9ac712947d7f1e59e3f806a91790", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00006__wfv__strict01-relids-qs-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-qs-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 1, "name": "strict01-relids-cs-image", "sha256": "d34388cd64f9a31f1f0d419b0b17315935b990a97ffe57f111e0de1d6cc75c2d", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00003__wfv__strict01-relids-cs-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-cs-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "strict01-relids-cs-image", "sha256": "d34388cd64f9a31f1f0d419b0b17315935b990a97ffe57f111e0de1d6cc75c2d", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00003__wfv__strict01-relids-cs-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-cs-image_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 1, "name": "s46a-control-minimal-end", "sha256": "20280914ae374d78fe2a7a7f3c14c2ff77e69694e3ee5dcd54a73af4982d54fb", "observedAt": "2026-10-26T09:17:30+00:00", "staged": "00000__wfv__s46a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46a", "pass": 2, "name": "s46a-control-minimal-end", "sha256": "20280914ae374d78fe2a7a7f3c14c2ff77e69694e3ee5dcd54a73af4982d54fb", "observedAt": "2026-10-26T09:20:34+00:00", "staged": "00000__wfv__s46a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 1, "name": "s46b-control-minimal", "sha256": "419d9468e4a06e19e37b8d6b01622b12da9fd9d0d1acb70d6a027ea4165d0cca", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00001__wfv__s46b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 2, "name": "s46b-control-minimal", "sha256": "419d9468e4a06e19e37b8d6b01622b12da9fd9d0d1acb70d6a027ea4165d0cca", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00001__wfv__s46b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 1, "name": "strict01-relids-lo-chart", "sha256": "69db2624180221cdeca1a0932ebf13d343191c93bca574361e8e8eeb4f40f104", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00005__wfv__strict01-relids-lo-chart.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-lo-chart_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 2, "name": "strict01-relids-lo-chart", "sha256": "69db2624180221cdeca1a0932ebf13d343191c93bca574361e8e8eeb4f40f104", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00005__wfv__strict01-relids-lo-chart.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-lo-chart_byword.pdf (1169010 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 1, "name": "strict01-chart-names-diagramdata", "sha256": "25ad45cfa8da12454eb7304779dbac1cfaea3d0d740c3ec1c708f2de63e75fe7", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00003__wfv__strict01-chart-names-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:18:55.340 Microsoft Word, Word found unreadable content in 00003__wfv__strict01-chart-names-diagramdata.docx.  … t? If you trust the source of this document, click Yes."]}
{"run": "s46b", "pass": 2, "name": "strict01-chart-names-diagramdata", "sha256": "25ad45cfa8da12454eb7304779dbac1cfaea3d0d740c3ec1c708f2de63e75fe7", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00003__wfv__strict01-chart-names-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:53.326 'Word found unreadable content in 00003__wfv__strict01-chart-names-diagramdata.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:53.892 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__strict01-chart-names-diag...)\""]}
{"run": "s46b", "pass": 1, "name": "strict01-chart-names-dangling", "sha256": "d6b56daa77e8c9f7188f7f9a45affda3ec1a0d8f52034f3bacb488a732f3a07b", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00002__wfv__strict01-chart-names-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:18:06.021 \"Word found unreadable content in 00002__wfv__strict01-chart-names-dangling.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s46b", "pass": 2, "name": "strict01-chart-names-dangling", "sha256": "d6b56daa77e8c9f7188f7f9a45affda3ec1a0d8f52034f3bacb488a732f3a07b", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00002__wfv__strict01-chart-names-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:49.081 'Word found unreadable content in 00002__wfv__strict01-chart-names-dangling.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:49.648 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__strict01-chart-names-dang...)\""]}
{"run": "s46b", "pass": 1, "name": "strict01-oleobject-names-image", "sha256": "6a9a819004265492d604cc5edcb42ce8b9453cafb877136a018ea261898ca9ff", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00004__wfv__strict01-oleobject-names-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:19:01.497 'Word found unreadable content in 00004__wfv__strict01-oleobject-names-image.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:19:07.226 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46b", "pass": 2, "name": "strict01-oleobject-names-image", "sha256": "6a9a819004265492d604cc5edcb42ce8b9453cafb877136a018ea261898ca9ff", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00004__wfv__strict01-oleobject-names-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:57.559 'Word found unreadable content in 00004__wfv__strict01-oleobject-names-image.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:58.156 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46b", "pass": 1, "name": "s46b-control-minimal-end", "sha256": "6285cc0181da338c66a68cd39764492bb472deba3c4f7025766e70584dae26e5", "observedAt": "2026-10-26T09:19:08+00:00", "staged": "00000__wfv__s46b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46b", "pass": 2, "name": "s46b-control-minimal-end", "sha256": "6285cc0181da338c66a68cd39764492bb472deba3c4f7025766e70584dae26e5", "observedAt": "2026-10-26T09:20:59+00:00", "staged": "00000__wfv__s46b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46c", "pass": 1, "name": "s46c-control-minimal", "sha256": "e345bd1fbcd8ff0d860dac5709beb9b58081c8f1c354f267f729d388edeb7718", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00001__wfv__s46c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46c", "pass": 2, "name": "s46c-control-minimal", "sha256": "e345bd1fbcd8ff0d860dac5709beb9b58081c8f1c354f267f729d388edeb7718", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00001__wfv__s46c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46c", "pass": 1, "name": "strict01-oleobject-names-chart", "sha256": "a6cd1dba57a2001d8710b097b2c52a70d440d3599b8dfc00a5193b364032eaf7", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00003__wfv__strict01-oleobject-names-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:19:27.993 'Word found unreadable content in 00003__wfv__strict01-oleobject-names-chart.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:19:28.681 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46c", "pass": 2, "name": "strict01-oleobject-names-chart", "sha256": "a6cd1dba57a2001d8710b097b2c52a70d440d3599b8dfc00a5193b364032eaf7", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00003__wfv__strict01-oleobject-names-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:21:18.525 'Word found unreadable content in 00003__wfv__strict01-oleobject-names-chart.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:21:19.127 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46c", "pass": 1, "name": "strict01-oleobject-names-dangling", "sha256": "c08cc69adac2650c9994643dc1c00fe296e4eeae45952236af268c449e265251", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00004__wfv__strict01-oleobject-names-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:19:32.227 'Word found unreadable content in 00004__wfv__strict01-oleobject-names-dangling.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:19:32.897 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46c", "pass": 2, "name": "strict01-oleobject-names-dangling", "sha256": "c08cc69adac2650c9994643dc1c00fe296e4eeae45952236af268c449e265251", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00004__wfv__strict01-oleobject-names-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:21:24.830 'Word found unreadable content in 00004__wfv__strict01-oleobject-names-dangling.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:21:25.764 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-oleobject-names-...)\""]}
{"run": "s46c", "pass": 1, "name": "strict01-relids-dm-dangling", "sha256": "fd5fc14d519d3a9d083520a4d92a12df114cc335eb90e0fd80bbff2d19ada48f", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00005__wfv__strict01-relids-dm-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:19:36.821 'Word found unreadable content in 00005__wfv__strict01-relids-dm-dangling.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:19:37.432 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__strict01-relids-dm-dangli...)\""]}
{"run": "s46c", "pass": 2, "name": "strict01-relids-dm-dangling", "sha256": "fd5fc14d519d3a9d083520a4d92a12df114cc335eb90e0fd80bbff2d19ada48f", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00005__wfv__strict01-relids-dm-dangling.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:21:43.585 'Word found unreadable content in 00005__wfv__strict01-relids-dm-dangling.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s46c", "pass": 1, "name": "strict01-chart-names-package", "sha256": "09ddf88b7734f73b3f8e21933e3e8e88f0dc136f7b1ee6e2c4abd41bc720cba8", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00002__wfv__strict01-chart-names-package.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:19:23.660 'Word found unreadable content in 00002__wfv__strict01-chart-names-package.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:19:24.425 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__strict01-chart-names-pack...)\""]}
{"run": "s46c", "pass": 2, "name": "strict01-chart-names-package", "sha256": "09ddf88b7734f73b3f8e21933e3e8e88f0dc136f7b1ee6e2c4abd41bc720cba8", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00002__wfv__strict01-chart-names-package.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:21:14.266 'Word found unreadable content in 00002__wfv__strict01-chart-names-package.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:21:14.848 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__strict01-chart-names-pack...)\""]}
{"run": "s46c", "pass": 1, "name": "s46c-control-minimal-end", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:19:37+00:00", "staged": "00000__wfv__s46c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46c", "pass": 2, "name": "s46c-control-minimal-end", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:21:52+00:00", "staged": "00000__wfv__s46c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 1, "name": "s46d-control-minimal", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:19:49+00:00", "staged": "00004__wfv__s46d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 2, "name": "s46d-control-minimal", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:22:06+00:00", "staged": "00004__wfv__s46d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 1, "name": "bar-image-reach-vml-imagedata-rid", "sha256": "d6e6a13beec866a971d7890d261a9c21ddda616aafc734292d1446c3dfc98ff8", "observedAt": "2026-10-26T09:19:49+00:00", "staged": "00002__wfv__bar-image-reach-vml-imagedata-rid.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-vml-imagedata-rid_byword.pdf (21471 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 2, "name": "bar-image-reach-vml-imagedata-rid", "sha256": "d6e6a13beec866a971d7890d261a9c21ddda616aafc734292d1446c3dfc98ff8", "observedAt": "2026-10-26T09:22:06+00:00", "staged": "00002__wfv__bar-image-reach-vml-imagedata-rid.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-vml-imagedata-rid_byword.pdf (21471 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 1, "name": "bar-image-reach-blip-link", "sha256": "9619415386768af710230f3caea95c3ecae544b86f97bf05b50fea5f7d4e2aba", "observedAt": "2026-10-26T09:19:49+00:00", "staged": "00001__wfv__bar-image-reach-blip-link.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-blip-link_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 2, "name": "bar-image-reach-blip-link", "sha256": "9619415386768af710230f3caea95c3ecae544b86f97bf05b50fea5f7d4e2aba", "observedAt": "2026-10-26T09:22:06+00:00", "staged": "00001__wfv__bar-image-reach-blip-link.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-blip-link_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 1, "name": "bar-image-reach-blip-embed", "sha256": "622d66a70a9583d3151c70d9998f67ce3aefe21c0be383bc4ce0aec9016351ed", "observedAt": "2026-10-26T09:19:49+00:00", "staged": "00000__wfv__bar-image-reach-blip-embed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-blip-embed_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 2, "name": "bar-image-reach-blip-embed", "sha256": "622d66a70a9583d3151c70d9998f67ce3aefe21c0be383bc4ce0aec9016351ed", "observedAt": "2026-10-26T09:22:06+00:00", "staged": "00000__wfv__bar-image-reach-blip-embed.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF bar-image-reach-blip-embed_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 1, "name": "s46d-control-minimal-end", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:19:49+00:00", "staged": "00003__wfv__s46d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46d", "pass": 2, "name": "s46d-control-minimal-end", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:22:06+00:00", "staged": "00003__wfv__s46d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 1, "name": "s46e-control-minimal", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00001__wfv__s46e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 2, "name": "s46e-control-minimal", "sha256": "b85a32b43261b0cb0128c0b85ccc5a61c1a0bf2bdbef2180573d41077c49846c", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00001__wfv__s46e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 1, "name": "styles-bin-not-xml", "sha256": "96fcc419c89e1bad67b3824e6bbf58fc4e8d1997fe495d209c3e874ddd4f8ab5", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00002__wfv__styles-bin-not-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:07.496 'Word found unreadable content in 00002__wfv__styles-bin-not-xml.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:08.131 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00002__wfv__styles-bin-not-xml.docx)\""]}
{"run": "s46e", "pass": 2, "name": "styles-bin-not-xml", "sha256": "96fcc419c89e1bad67b3824e6bbf58fc4e8d1997fe495d209c3e874ddd4f8ab5", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00002__wfv__styles-bin-not-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:26:34.348 \"Word found unreadable content in 00002__wfv__styles-bin-not-xml.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\"", "2026-10-26 05:26:34.349 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00002__wfv__styles-bin-not-xml.docx)\""]}
{"run": "s46e", "pass": 1, "name": "styles-bin-xml-octet-stream", "sha256": "a9cec79ea237e1c93ca6ed5c6a6a7123803557e2ea4223fa06509bc5be53ea0f", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00003__wfv__styles-bin-xml-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:20:11.776 'Word found unreadable content in 00003__wfv__styles-bin-xml-octet-stream.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:20:12.399 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-bin-xml-octet-stre...)\""]}
{"run": "s46e", "pass": 2, "name": "styles-bin-xml-octet-stream", "sha256": "a9cec79ea237e1c93ca6ed5c6a6a7123803557e2ea4223fa06509bc5be53ea0f", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00003__wfv__styles-bin-xml-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 05:27:04.145 'Word found unreadable content in 00003__wfv__styles-bin-xml-octet-stream.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 05:27:05.065 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-bin-xml-octet-stre...)\""]}
{"run": "s46e", "pass": 1, "name": "styles-bin-xml-styles-type", "sha256": "f584ed6d48614fe0fa3db17f2fdb4b6df8a7b6f224f9347393f6e4d486982acf", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00004__wfv__styles-bin-xml-styles-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-bin-xml-styles-type_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 2, "name": "styles-bin-xml-styles-type", "sha256": "f584ed6d48614fe0fa3db17f2fdb4b6df8a7b6f224f9347393f6e4d486982acf", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00004__wfv__styles-bin-xml-styles-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-bin-xml-styles-type_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 1, "name": "styles-visible-only", "sha256": "f555b59f96a8abee5cdcae47cefaab434cda44aa44bd85936bea3ea9d92a3dde", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00005__wfv__styles-visible-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-visible-only_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 2, "name": "styles-visible-only", "sha256": "f555b59f96a8abee5cdcae47cefaab434cda44aa44bd85936bea3ea9d92a3dde", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00005__wfv__styles-visible-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-visible-only_byword.pdf (16329 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 1, "name": "s46e-control-minimal-end", "sha256": "16a83807f8f1a5cd0ec376508f7ec1e1094c647699b6e795fdba42e9526deaa3", "observedAt": "2026-10-26T09:20:13+00:00", "staged": "00000__wfv__s46e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s46e", "pass": 2, "name": "s46e-control-minimal-end", "sha256": "16a83807f8f1a5cd0ec376508f7ec1e1094c647699b6e795fdba42e9526deaa3", "observedAt": "2026-10-26T09:27:06+00:00", "staged": "00000__wfv__s46e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s46e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 46 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s46builder.mts`:

```ts
// Session 46 (2026-10-26): the shapes #705, #706 and #707 left unobserved.
// s46a-s46c, #705: reference-type mismatches on a Word-clean ISO Strict document with a SmartArt (dgm:relIds rId35-38),
// a chart (c:chart rId8), an embedded Excel OLE object (o:OLEObject rId19, a `package` relationship, in an
// mc:Choice Requires="v" Word selects) and an EMF picture (rId18, image): tests/fixtures/working/word-clean-strict01.docx
// (clean-open, 2026-10-23). Each specimen changes one attribute of word/document.xml; `strict01-rebuilt` is the
// fixture re-zipped unchanged, the calibration for the rebuild.
// s46d, #706: a bar chart with c:externalData and no sidecar, reached by an image relationship, named by a VML
// picture (v:imagedata r:id) or a linked picture (a:blip r:link); the a:blip r:embed control of session 44.
// s46e, #707: the main document's styles relationship names word/styles.bin: non-XML bytes, or styles XML with an
// application/octet-stream type, or styles XML with the styles content type (an XML part by content type).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s46a pnpm exec tsx s46builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

type Parts = Record<string, string>;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
const DGM = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
const O = "urn:schemas-microsoft-com:office:office";
const V = "urn:schemas-microsoft-com:vml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN = "word/document.xml";
const STYLES_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
const MAIN_CT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
const CHART_CT = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, type: string, target: string, external = false) =>
    `<Relationship Id="${id}" Type="${type}" Target="${target}"${external ? ' TargetMode="External"' : ""}/>`;
const OFFICE = (segment: string) => `${R}/${segment}`;
const relsPart = (...relationships: string[]) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationships.join("")}</Relationships>`;
const withOverrides = (...overrides: Array<[string, string]>) =>
    replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

// ---- #694: styles
const heading1 = (vanish: boolean) =>
    `<w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><w:basedOn w:val="Normal"/>${vanish ? "<w:rPr><w:vanish/></w:rPr>" : ""}</w:style>`;
const stylesWith = (vanish: boolean) => replaceOnce(MINIMAL_PARTS["word/styles.xml"]!, "</w:styles>", `${heading1(vanish)}</w:styles>`);
const MARKER_DOCUMENT = replaceOnce(
    MINIMAL_PARTS[MAIN]!,
    "<w:sectPr>",
    '<w:p w14:paraId="00000003" w14:textId="00000003"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>MARKER</w:t></w:r></w:p><w:sectPr>',
);
/** `rels` lists [Id, target] in document order; `contents` maps each styles part name to whether its Heading1 vanishes. */
const stylesSpecimen = (rels: Array<[string, string]>, contents: Record<string, boolean>): Parts => ({
    ...Object.fromEntries(Object.entries(MINIMAL_PARTS).filter(([name]) => name !== "word/styles.xml")),
    [MAIN]: MARKER_DOCUMENT,
    [SIDECAR]: relsPart(...rels.map(([id, target]) => relationship(id, OFFICE("styles"), target))),
    ...Object.fromEntries(Object.entries(contents).map(([name, vanish]) => [`word/${name}`, stylesWith(vanish)])),
    [CT]: withOverrides(
        ...Object.keys(contents)
            .filter((name) => name !== "styles.xml")
            .map((name): [string, string] => [`word/${name}`, STYLES_CT]),
    ),
});

// ---- #694: two main documents
const mainSaying = (text: string) => replaceOnce(MINIMAL_PARTS[MAIN]!, "<w:t>Hello</w:t>", `<w:t>${text}</w:t>`);
/** `rels` lists [Id, target] of `_rels/.rels` in document order; `texts` maps each main part to its text. */
const twoMains = (rels: Array<[string, string]>, texts: Record<string, string>): Parts => ({
    ...MINIMAL_PARTS,
    "_rels/.rels": relsPart(...rels.map(([id, target]) => relationship(id, OFFICE("officeDocument"), target))),
    ...Object.fromEntries(Object.entries(texts).map(([part, text]) => [part, mainSaying(text)])),
    "word/_rels/document2.xml.rels": MINIMAL_PARTS[SIDECAR]!,
    [CT]: withOverrides(["word/document2.xml", MAIN_CT]),
});

// ---- #702 / #701: the bare chart with no sidecar
const CHART_INSIDE = "word/charts/chart1.xml";
const CHART_OUTSIDE = "charts/chart1.xml";
const BARE_CHART = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart><c:externalData r:id="rId1"/></c:chartSpace>`;
const targetOf = (part: string) => (part === CHART_INSIDE ? "charts/chart1.xml" : `../${part}`);
const reached = (part: string, ...relationships: string[]): Parts => ({
    ...MINIMAL_PARTS,
    [part]: BARE_CHART,
    [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`),
    [CT]: withOverrides([part, CHART_CT]),
});
const PICTURE_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    '<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Picture 1"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr>' +
    `<a:graphic><a:graphicData uri="${PIC}"><pic:pic><pic:nvPicPr><pic:cNvPr id="0" name="Picture 1"/><pic:cNvPicPr/></pic:nvPicPr>` +
    `<pic:blipFill><a:blip r:embed="${id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>` +
    '<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="952500" cy="952500"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>' +
    "</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>";
const CHART_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart r:id="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const DIAGRAM_DRAWING = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Diagram 1"/><a:graphic><a:graphicData uri="${DGM}">` +
    `<dgm:relIds xmlns:dgm="${DGM}" r:dm="${id}" r:lo="${id}" r:qs="${id}" r:cs="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const VML_IMAGEDATA = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:pict>' +
    `<v:shape xmlns:v="${V}" xmlns:o="${O}" id="s1" style="width:10pt;height:10pt"><v:imagedata o:relid="${id}"/></v:shape></w:pict></w:r></w:p>`;
const OLE_OBJECT = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:object>' +
    `<o:OLEObject xmlns:o="${O}" Type="Embed" ProgID="Package" ShapeID="_x0000_i1025" DrawAspect="Icon" ObjectID="_1" r:id="${id}"/></w:object></w:r></w:p>`;
const withDrawing = (parts: Parts, drawing: string): Parts => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            MINIMAL_PARTS[MAIN]!,
            "<w:document ",
            `<w:document xmlns:wp="${WP}" xmlns:a="${A}" xmlns:pic="${PIC}" xmlns:c="${C}" xmlns:r="${R}" `,
        ),
        "<w:sectPr>",
        `${drawing}<w:sectPr>`,
    ),
});
const typed = (part: string, id: string, segment: string, external = false) =>
    relationship(id, OFFICE(segment), external ? "charts/chart1.xml" : targetOf(part), external);
const control = () => buildDocx({ ...MINIMAL_PARTS });

// ---- session 45 follow-ups: cause controls for s45b-d, and the scope of #694's refusal
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "base64"),
);
const CHART_NO_EXTERNAL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:r="${R}"><c:chart><c:plotArea><c:layout/></c:plotArea></c:chart></c:chartSpace>`;
/** The minimal package plus `parts`, with `relationships` appended to the main document's sidecar. */
const extended = (
    parts: Record<string, string | Uint8Array>,
    relationships: string[],
    overrides: Array<[string, string]>,
    pngDefault = false,
) => ({
    ...MINIMAL_PARTS,
    ...parts,
    [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`),
    [CT]: replaceOnce(
        withOverrides(...overrides),
        '<Default Extension="rels"',
        `${pngDefault ? '<Default Extension="png" ContentType="image/png"/>' : ""}<Default Extension="rels"`,
    ),
});
const withDrawingAny = (parts: Record<string, string | Uint8Array>, drawing: string) => withDrawing(parts as Parts, drawing);
const pngReached = () => extended({ "word/media/image1.png": PNG }, [relationship("rId8", OFFICE("image"), "media/image1.png")], [], true);
const SINGLETONS: Record<string, { root: string; ct: string }> = {
    settings: { root: `<w:settings xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" },
    fontTable: { root: `<w:fonts xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" },
    numbering: {
        root: `<w:numbering xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
    },
    webSettings: {
        root: `<w:webSettings xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
    },
    footnotes: {
        root: `<w:footnotes xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
    },
};
/** One relationship of `segment` per name in `names`, each to its own part `word/<name>`, all holding the same minimal root. */
const singletonSpecimen = (segment: string, names: string[]) => {
    const { root, ct } = SINGLETONS[segment]!;
    const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n${root}`;
    return extended(
        Object.fromEntries(names.map((name) => [`word/${name}`, xml])),
        names.map((name, index) => relationship(`rId${index + 2}`, OFFICE(segment), name)),
        names.map((name): [string, string] => [`word/${name}`, ct]),
    );
};

// ---- s45h-k: s45e again in small chunks, with session 36d's real clustered bar chart in place of the bare plotArea
// (s45e's first run got an open error for the bare chart with no c:externalData under c:chart, so the bare chart's
// content, not only its missing sidecar, may be what Word refuses once something makes it load the chart).
const BAR_PLOT_AREA =
    '<c:plotArea><c:layout/><c:barChart><c:barDir val="col"/><c:grouping val="clustered"/><c:ser><c:idx val="0"/><c:order val="0"/>' +
    '<c:val><c:numLit><c:ptCount val="1"/><c:pt idx="0"><c:v>1</c:v></c:pt></c:numLit></c:val></c:ser><c:axId val="1"/><c:axId val="2"/></c:barChart>' +
    '<c:catAx><c:axId val="1"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="b"/><c:crossAx val="2"/></c:catAx>' +
    '<c:valAx><c:axId val="2"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="l"/><c:crossAx val="1"/></c:valAx></c:plotArea>';
const barChart = (externalData: boolean) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<c:chartSpace xmlns:c="${C}" xmlns:a="${A}" xmlns:r="${R}"><c:chart>${BAR_PLOT_AREA}</c:chart>${externalData ? '<c:externalData r:id="rId1"/>' : ""}</c:chartSpace>`;
/** The bar chart at word/charts/chart1.xml (no sidecar), reached from the main document's sidecar as `rId` of `segment`. */
const barReached = (externalData: boolean, id: string, segment: string) =>
    extended(
        { [CHART_INSIDE]: barChart(externalData) },
        [relationship(id, OFFICE(segment), "charts/chart1.xml")],
        [[CHART_INSIDE, CHART_CT]],
    );

// ---- s46a-c: one-attribute mutations of the Word-clean Strict document
import JSZip from "jszip";
import { readFileSync } from "node:fs";
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strictVariant = async (from?: string, to?: string) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) {
        if (entry.dir) continue;
        parts[name] = await entry.async("uint8array");
    }
    if (from !== undefined && to !== undefined) {
        parts[MAIN] = replaceOnce(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"), from, to);
    }
    return buildDocx(parts);
};
const RELIDS = 'r:dm="rId35" r:lo="rId36" r:qs="rId37" r:cs="rId38"';
const relIds = (attribute: "dm" | "lo" | "qs" | "cs", id: string) =>
    strictVariant(RELIDS, RELIDS.replace(new RegExp(`r:${attribute}="rId\\d+"`), `r:${attribute}="${id}"`));
const CHART_REF = 'r:id="rId8"/></a:graphicData>';
const chartNames = (id: string) => strictVariant(CHART_REF, `r:id="${id}"/></a:graphicData>`);
const OLE_REF = 'ObjectID="_1509346857" r:id="rId19"/>';
const oleNames = (id: string) => strictVariant(OLE_REF, `ObjectID="_1509346857" r:id="${id}"/>`);

// ---- s46d: #706's picture shapes naming an image relationship to a chart part with no sidecar
const VML_PICTURE_RID = (id: string) =>
    '<w:p w14:paraId="00000002" w14:textId="00000002"><w:r><w:pict>' +
    `<v:shape xmlns:v="${V}" xmlns:o="${O}" id="s1" style="width:10pt;height:10pt"><v:imagedata r:id="${id}" o:title=""/></v:shape></w:pict></w:r></w:p>`;
const LINKED_PICTURE = (id: string) => replaceOnce(PICTURE_DRAWING(id), `<a:blip r:embed="${id}"/>`, `<a:blip r:link="${id}"/>`);

// ---- s46e: #707's styles part stored as word/styles.bin
const STYLES_OVERRIDE =
    '<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>';
const stylesBin = (bytes: string | Uint8Array, asStyles: boolean): Record<string, string | Uint8Array> => {
    const base = Object.fromEntries(Object.entries(MINIMAL_PARTS).filter(([name]) => name !== "word/styles.xml"));
    const types = replaceOnce(
        MINIMAL_PARTS[CT]!,
        STYLES_OVERRIDE,
        asStyles ? `<Override PartName="/word/styles.bin" ContentType="${STYLES_CT}"/>` : "",
    );
    return {
        ...base,
        [MAIN]: MARKER_DOCUMENT,
        [SIDECAR]: replaceOnce(MINIMAL_PARTS[SIDECAR]!, 'Target="styles.xml"', 'Target="styles.bin"'),
        "word/styles.bin": bytes,
        [CT]: asStyles
            ? types
            : replaceOnce(
                  types,
                  '<Default Extension="rels"',
                  '<Default Extension="bin" ContentType="application/octet-stream"/><Default Extension="rels"',
              ),
    };
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s46a: [
        ["s46a-control-minimal", "control", control],
        ["strict01-rebuilt", "calibration: word-clean-strict01.docx re-zipped unchanged", () => strictVariant()],
        ["strict01-relids-dm-image", "#705: SmartArt dgm:relIds r:dm names the EMF image relationship rId18", () => relIds("dm", "rId18")],
        ["strict01-relids-lo-image", "#705: SmartArt dgm:relIds r:lo names the EMF image relationship rId18", () => relIds("lo", "rId18")],
        ["strict01-relids-qs-image", "#705: SmartArt dgm:relIds r:qs names the EMF image relationship rId18", () => relIds("qs", "rId18")],
        ["strict01-relids-cs-image", "#705: SmartArt dgm:relIds r:cs names the EMF image relationship rId18", () => relIds("cs", "rId18")],
        ["s46a-control-minimal-end", "control", control],
    ],
    s46b: [
        ["s46b-control-minimal", "control", control],
        ["strict01-relids-lo-chart", "#705: SmartArt dgm:relIds r:lo names the chart relationship rId8", () => relIds("lo", "rId8")],
        ["strict01-chart-names-diagramdata", "#705: c:chart r:id names the diagramData relationship rId35", () => chartNames("rId35")],
        ["strict01-chart-names-dangling", "#705: c:chart r:id names rId999, which no relationship has", () => chartNames("rId999")],
        [
            "strict01-oleobject-names-image",
            "#705: o:OLEObject r:id (selected mc:Choice) names the EMF image relationship rId18",
            () => oleNames("rId18"),
        ],
        ["s46b-control-minimal-end", "control", control],
    ],
    s46c: [
        ["s46c-control-minimal", "control", control],
        ["strict01-oleobject-names-chart", "#705: o:OLEObject r:id names the chart relationship rId8", () => oleNames("rId8")],
        ["strict01-oleobject-names-dangling", "#705: o:OLEObject r:id names rId999, which no relationship has", () => oleNames("rId999")],
        [
            "strict01-relids-dm-dangling",
            "#705: SmartArt dgm:relIds r:dm names rId999, which no relationship has",
            () => relIds("dm", "rId999"),
        ],
        [
            "strict01-chart-names-package",
            "#705: c:chart r:id names the package (embedded workbook) relationship rId19",
            () => chartNames("rId19"),
        ],
        ["s46c-control-minimal-end", "control", control],
    ],
    s46d: [
        ["s46d-control-minimal", "control", control],
        [
            "bar-image-reach-vml-imagedata-rid",
            "#706 shape 2: bar chart with c:externalData, no sidecar, image reach, v:imagedata r:id names it",
            () => buildDocx(withDrawingAny(barReached(true, "rId8", "image"), VML_PICTURE_RID("rId8"))),
        ],
        [
            "bar-image-reach-blip-link",
            "#706 shape 3: bar chart with c:externalData, no sidecar, image reach, a:blip r:link names it",
            () => buildDocx(withDrawingAny(barReached(true, "rId8", "image"), LINKED_PICTURE("rId8"))),
        ],
        [
            "bar-image-reach-blip-embed",
            "control (session 44's clean shape, bar chart): image reach, a:blip r:embed names it",
            () => buildDocx(withDrawingAny(barReached(true, "rId8", "image"), PICTURE_DRAWING("rId8"))),
        ],
        ["s46d-control-minimal-end", "control", control],
    ],
    s46e: [
        ["s46e-control-minimal", "control", control],
        [
            "styles-bin-not-xml",
            "#707: styles relationship names word/styles.bin holding non-XML bytes (application/octet-stream)",
            () => buildDocx(stylesBin("this is not XML", false)),
        ],
        [
            "styles-bin-xml-octet-stream",
            "#707: word/styles.bin holds styles XML (Heading1 visible), typed application/octet-stream",
            () => buildDocx(stylesBin(stylesWith(false), false)),
        ],
        [
            "styles-bin-xml-styles-type",
            "#707 control: word/styles.bin holds styles XML (Heading1 visible), typed as styles",
            () => buildDocx(stylesBin(stylesWith(false), true)),
        ],
        [
            "styles-visible-only",
            "control (session 45, clean): one styles relationship to word/styles.xml, Heading1 visible",
            () => buildDocx(stylesSpecimen([["rId1", "styles.xml"]], { "styles.xml": false })),
        ],
        ["s46e-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = { name, issue, file, sha256, calibration: false, wordValid: await verdict("word-valid"), strict: await verdict("strict") };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-46 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s46a", "s46b", "s46c", "s46d", "s46e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s46/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-46 parts of docs/plans/evidence/word-probes-2026-10-24.md into s46/section.md.

Reads each chunk's specimens.jsonl (validator columns at f2717ba3, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s46/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s46a", "s46b", "s46c", "s46d", "s46e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s46/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 46: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at f2717ba3",
    "",
    "The shapes [#705](https://github.com/jandira-tech/docx-validate/issues/705), "
    "[#706](https://github.com/jandira-tech/docx-validate/issues/706) and "
    "[#707](https://github.com/jandira-tech/docx-validate/issues/707) left unobserved. Each chunk ran twice, as two separate "
    "driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, "
    "and `unknown` otherwise; all 30 rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen.",
    "",
    "- `s46a`–`s46c`, #705, on `tests/fixtures/working/word-clean-strict01.docx` (an ISO Strict document Word opened clean on "
    "2026-10-23, with a SmartArt, a chart, an embedded Excel object and an EMF picture), one attribute of "
    "`word/document.xml` changed per specimen; the fixture re-zipped unchanged opens clean. `dgm:relIds r:dm` naming the "
    "image relationship or an Id no relationship has gets the recovery offer; `r:lo`, `r:qs` or `r:cs` naming the image "
    "relationship, and `r:lo` naming the chart relationship, open clean (the part keeps its cached `diagramDrawing`). "
    "`c:chart r:id` naming the `diagramData` or the `package` relationship, or an Id no relationship has, gets the "
    "recovery offer. `o:OLEObject r:id` in the selected `mc:Choice` naming the image or the chart relationship, or an Id no "
    "relationship has, gets the recovery offer; the fixture's own `package` relationship opens clean. Word-valid passes "
    "every refused row.",
    "- `s46d`, #706, with session 36d's bar chart (`c:externalData r:id`, no sidecar) reached by an `image` relationship: "
    "a VML picture (`v:imagedata r:id`) or a linked picture (`a:blip r:link`) naming it opens clean, as the `a:blip "
    "r:embed` control does. Word-valid rejects the first two with `rels-missing-sidecar` (#701's extension).",
    "- `s46e`, #707: the main document's `styles` relationship naming `word/styles.bin` gets the recovery offer when the "
    "part holds non-XML bytes or styles XML typed `application/octet-stream`, and opens clean when the same XML is typed "
    "as styles. Word-valid passes all three.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at f2717ba3 | strict at f2717ba3 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 46</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 46 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s46builder.mts", ROOT / "s46builder.mts", "ts"), ("compare.py", ROOT / "s46/compare.py", "python"),
                         ("section.py", ROOT / "s46/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s46/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 47: 10:04Z–10:06Z on 2026-10-26, validator columns at f2717ba3

Does Word count a relationship whose Type only ends in a single-instance segment ([#708](https://github.com/jandira-tech/docx-validate/issues/708), [#694](https://github.com/jandira-tech/docx-validate/issues/694))? Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 13 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- Each specimen is the minimal package plus one real relationship of the segment (styles reuses the minimal `rId1`) and one relationship whose Type only ends in the segment: `…/relationships/custom/<segment>` or `http://example.com/<segment>`, to its own part typed with the segment's content type, or for styles also to the real part. Word opens every one clean: it reads `custom/styles`, `custom/numbering`, `custom/settings`, `custom/webSettings`, `custom/fontTable`, `http://example.com/styles` and `http://example.com/settings` as no relationship of the segment, as session 27 found for `header`. Word-valid at f2717ba3 rejects the settings, webSettings and fontTable rows through the suffix-matching duplicate rules (#708, false positives).
- Calibration: two real settings relationships to two parts (session 45's refused shape) get the recovery offer again.

| Run    | Observed             | Specimen                             | Shape                                                                                              | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f2717ba3                              | strict at f2717ba3                                  |
| ------ | -------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | --------------------------------------------------- | --------------------------------------------------- |
| `s47a` | 10:04:50Z, 10:06:09Z | `s47a-control-minimal`               | control                                                                                            | `5a4910cb77ad15ea` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47a` | 10:04:50Z, 10:06:09Z | `styles-custom-styles-own`           | suffix: rId1 styles→styles.xml, rId3 …/relationships/custom/styles→styles2.xml (styles type)       | `55bf333b83b378f0` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47a` | 10:04:50Z, 10:06:09Z | `styles-custom-styles-same`          | suffix: rId1 styles→styles.xml, rId3 …/relationships/custom/styles→styles.xml                      | `2ba7eb59ffb7a8ef` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47a` | 10:04:50Z, 10:06:09Z | `styles-foreign-styles-own`          | suffix: rId1 styles→styles.xml, rId3 http://example.com/styles→styles2.xml (styles type)           | `0ccb33097c032370` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47a` | 10:04:50Z, 10:06:09Z | `numbering-custom-numbering-own`     | suffix: rId2 numbering→numbering.xml, rId3 …/relationships/custom/numbering→numbering2.xml         | `77c2f51ba2810cc6` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47a` | 10:04:50Z, 10:06:09Z | `settings-custom-settings-own`       | suffix: rId2 settings→settings.xml, rId3 …/relationships/custom/settings→settings2.xml             | `85d3fa3c44cdf381` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`     |
| `s47a` | 10:04:50Z, 10:06:09Z | `settings-foreign-settings-own`      | suffix: rId2 settings→settings.xml, rId3 http://example.com/settings→settings2.xml                 | `64ef766f18a9dd88` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`     |
| `s47a` | 10:04:50Z, 10:06:09Z | `s47a-control-minimal-end`           | control                                                                                            | `d60bdb5d94b92954` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47b` | 10:05:29Z, 10:06:25Z | `s47b-control-minimal`               | control                                                                                            | `d60bdb5d94b92954` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |
| `s47b` | 10:05:29Z, 10:06:25Z | `websettings-custom-websettings-own` | suffix: rId2 webSettings→webSettings.xml, rId3 …/relationships/custom/webSettings→webSettings2.xml | `ecf8d61e14839ab0` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-web-settings-relationship` | invalid: `word-duplicate-web-settings-relationship` |
| `s47b` | 10:05:29Z, 10:06:25Z | `fonttable-custom-fonttable-own`     | suffix: rId2 fontTable→fontTable.xml, rId3 …/relationships/custom/fontTable→fontTable2.xml         | `ae042e184aee9d7d` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-font-table-relationship`   | invalid: `word-duplicate-font-table-relationship`   |
| `s47b` | 10:05:29Z, 10:06:25Z | `settings-dup-calibration`           | calibration (s45f's refused shape): two settings relationships to two parts                        | `586c942eed232613` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`     |
| `s47b` | 10:05:29Z, 10:06:25Z | `s47b-control-minimal-end`           | control                                                                                            | `72c3f823e4b3aa1a` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                               |

<details><summary>Raw records, session 47</summary>

```jsonl
{"run": "s47a", "pass": 1, "name": "s47a-control-minimal", "sha256": "5a4910cb77ad15eaf9b0ef5f9d4b996e2ee01db518ea2a7b782ac13792fc3587", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00002__wfv__s47a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "s47a-control-minimal", "sha256": "5a4910cb77ad15eaf9b0ef5f9d4b996e2ee01db518ea2a7b782ac13792fc3587", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00002__wfv__s47a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "styles-custom-styles-own", "sha256": "55bf333b83b378f0971721ef1b732c1ca9c053b49aeb2729ecdbfd04d1545148", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00005__wfv__styles-custom-styles-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-custom-styles-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "styles-custom-styles-own", "sha256": "55bf333b83b378f0971721ef1b732c1ca9c053b49aeb2729ecdbfd04d1545148", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00005__wfv__styles-custom-styles-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-custom-styles-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "styles-custom-styles-same", "sha256": "2ba7eb59ffb7a8ef388d64e90899b7840f5115b3a14e15cc6c62a463a20dc386", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00006__wfv__styles-custom-styles-same.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-custom-styles-same_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "styles-custom-styles-same", "sha256": "2ba7eb59ffb7a8ef388d64e90899b7840f5115b3a14e15cc6c62a463a20dc386", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00006__wfv__styles-custom-styles-same.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-custom-styles-same_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "styles-foreign-styles-own", "sha256": "0ccb33097c032370e3c20c43b5309b8f096d80d3d1dd39652bd4ccb992dde435", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00007__wfv__styles-foreign-styles-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-foreign-styles-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "styles-foreign-styles-own", "sha256": "0ccb33097c032370e3c20c43b5309b8f096d80d3d1dd39652bd4ccb992dde435", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00007__wfv__styles-foreign-styles-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-foreign-styles-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "numbering-custom-numbering-own", "sha256": "77c2f51ba2810cc6335f1abc0c3efd364e8311a68d57b7267e65d15ce7b32c17", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00000__wfv__numbering-custom-numbering-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-custom-numbering-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "numbering-custom-numbering-own", "sha256": "77c2f51ba2810cc6335f1abc0c3efd364e8311a68d57b7267e65d15ce7b32c17", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00000__wfv__numbering-custom-numbering-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-custom-numbering-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "settings-custom-settings-own", "sha256": "85d3fa3c44cdf381d7ef5b6b1f448670981d58dadf2a88f4c35eb9c27e21c73a", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00003__wfv__settings-custom-settings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-custom-settings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "settings-custom-settings-own", "sha256": "85d3fa3c44cdf381d7ef5b6b1f448670981d58dadf2a88f4c35eb9c27e21c73a", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00003__wfv__settings-custom-settings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-custom-settings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "settings-foreign-settings-own", "sha256": "64ef766f18a9dd88449a45d24b0ef45b029eb13ad2adfb915b8455627dbd1a81", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00004__wfv__settings-foreign-settings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-foreign-settings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "settings-foreign-settings-own", "sha256": "64ef766f18a9dd88449a45d24b0ef45b029eb13ad2adfb915b8455627dbd1a81", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00004__wfv__settings-foreign-settings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-foreign-settings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 1, "name": "s47a-control-minimal-end", "sha256": "d60bdb5d94b92954f291ac13ee9e87a694de17dd1bff09c80be4d9a1e67e3897", "observedAt": "2026-10-26T10:04:50+00:00", "staged": "00001__wfv__s47a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47a", "pass": 2, "name": "s47a-control-minimal-end", "sha256": "d60bdb5d94b92954f291ac13ee9e87a694de17dd1bff09c80be4d9a1e67e3897", "observedAt": "2026-10-26T10:06:09+00:00", "staged": "00001__wfv__s47a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 1, "name": "s47b-control-minimal", "sha256": "d60bdb5d94b92954f291ac13ee9e87a694de17dd1bff09c80be4d9a1e67e3897", "observedAt": "2026-10-26T10:05:29+00:00", "staged": "00002__wfv__s47b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 2, "name": "s47b-control-minimal", "sha256": "d60bdb5d94b92954f291ac13ee9e87a694de17dd1bff09c80be4d9a1e67e3897", "observedAt": "2026-10-26T10:06:25+00:00", "staged": "00002__wfv__s47b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 1, "name": "websettings-custom-websettings-own", "sha256": "ecf8d61e14839ab0c9abf62c325552d69104dac8f4980f3369a036ac952aa721", "observedAt": "2026-10-26T10:05:29+00:00", "staged": "00004__wfv__websettings-custom-websettings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF websettings-custom-websettings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 2, "name": "websettings-custom-websettings-own", "sha256": "ecf8d61e14839ab0c9abf62c325552d69104dac8f4980f3369a036ac952aa721", "observedAt": "2026-10-26T10:06:25+00:00", "staged": "00004__wfv__websettings-custom-websettings-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF websettings-custom-websettings-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 1, "name": "fonttable-custom-fonttable-own", "sha256": "ae042e184aee9d7d90b5d8fd19269f6cacd2df0e8a74ead3bb237fb734a085f3", "observedAt": "2026-10-26T10:05:29+00:00", "staged": "00000__wfv__fonttable-custom-fonttable-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF fonttable-custom-fonttable-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 2, "name": "fonttable-custom-fonttable-own", "sha256": "ae042e184aee9d7d90b5d8fd19269f6cacd2df0e8a74ead3bb237fb734a085f3", "observedAt": "2026-10-26T10:06:25+00:00", "staged": "00000__wfv__fonttable-custom-fonttable-own.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF fonttable-custom-fonttable-own_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 1, "name": "settings-dup-calibration", "sha256": "586c942eed2326138b44cdceeb2b99b9a2f9d17a973fa9489fab81e332541e25", "observedAt": "2026-10-26T10:05:29+00:00", "staged": "00003__wfv__settings-dup-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:05:12.810 'Word found unreadable content in 00003__wfv__settings-dup-calibration.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:05:20.283 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-dup-calibration....)\""]}
{"run": "s47b", "pass": 2, "name": "settings-dup-calibration", "sha256": "586c942eed2326138b44cdceeb2b99b9a2f9d17a973fa9489fab81e332541e25", "observedAt": "2026-10-26T10:06:25+00:00", "staged": "00003__wfv__settings-dup-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:06:24.352 'Word found unreadable content in 00003__wfv__settings-dup-calibration.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:06:25.089 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-dup-calibration....)\""]}
{"run": "s47b", "pass": 1, "name": "s47b-control-minimal-end", "sha256": "72c3f823e4b3aa1a2bc8fc6d1888b09c5d43fc3565e79ce35ee47f08baec36f5", "observedAt": "2026-10-26T10:05:29+00:00", "staged": "00001__wfv__s47b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s47b", "pass": 2, "name": "s47b-control-minimal-end", "sha256": "72c3f823e4b3aa1a2bc8fc6d1888b09c5d43fc3565e79ce35ee47f08baec36f5", "observedAt": "2026-10-26T10:06:25+00:00", "staged": "00001__wfv__s47b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s47b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 47 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s47builder.mts`:

```ts
// Session 47 (2026-10-26): does Word count a relationship whose Type only ENDS in a single-instance segment?
// The duplicate-relationship rules (theme, fontTable, webSettings, settings; #694's styles and numbering) match
// `type.endsWith("/<segment>")`, so `…/relationships/custom/styles` and `http://example.com/settings` count as a
// second styles / settings relationship, while #519 reads a type as an Office segment only when it is the
// Transitional or Strict namespace plus exactly one segment. Session 45 showed Word refuses two real styles,
// numbering, settings, fontTable or webSettings relationships; it never saw a real one beside a suffix-only one.
// Each specimen is the minimal package (one styles relationship rId1) plus one real relationship of the segment
// (except styles, which already has rId1) and one suffix-only relationship, each to its own part typed with the
// segment's content type ("own") or to the real relationship's part ("same").
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s47a pnpm exec tsx s47builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, type: string, target: string) => `<Relationship Id="${id}" Type="${type}" Target="${target}"/>`;
const OFFICE = (segment: string) => `${R}/${segment}`;
const withOverrides = (...overrides: Array<[string, string]>) =>
    replaceOnce(
        MINIMAL_PARTS[CT]!,
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...MINIMAL_PARTS });

const SINGLETONS: Record<string, { root: string; ct: string }> = {
    styles: { root: `<w:styles xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" },
    settings: { root: `<w:settings xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" },
    fontTable: { root: `<w:fonts xmlns:w="${W}"/>`, ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" },
    numbering: {
        root: `<w:numbering xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
    },
    webSettings: {
        root: `<w:webSettings xmlns:w="${W}"/>`,
        ct: "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
    },
};
const xmlOf = (segment: string) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n${SINGLETONS[segment]!.root}`;

/**
 * The minimal package plus one real `segment` relationship (styles reuses the minimal rId1 → styles.xml) and one
 * relationship of `suffixType`: to its own part `word/<segment>2.xml` typed with the segment's content type when
 * `own`, else to the real relationship's part.
 */
const suffixSpecimen = (segment: string, suffixType: string, own: boolean) => {
    const real = `${segment}.xml`;
    const second = own ? `${segment}2.xml` : real;
    const parts: Record<string, string> = { ...MINIMAL_PARTS };
    const relationships: string[] = [];
    const overrides: Array<[string, string]> = [];
    if (segment !== "styles") {
        parts[`word/${real}`] = xmlOf(segment);
        relationships.push(relationship("rId2", OFFICE(segment), real));
        overrides.push([`word/${real}`, SINGLETONS[segment]!.ct]);
    }
    if (own) {
        parts[`word/${second}`] = xmlOf(segment);
        overrides.push([`word/${second}`, SINGLETONS[segment]!.ct]);
    }
    relationships.push(relationship("rId3", suffixType, second));
    parts[SIDECAR] = replaceOnce(MINIMAL_PARTS[SIDECAR]!, "</Relationships>", `${relationships.join("")}</Relationships>`);
    parts[CT] = withOverrides(...overrides);
    return buildDocx(parts);
};
/** Two real `segment` relationships to two parts: session 45's refused shape, the run's calibration. */
const realPair = (segment: string) => {
    const parts: Record<string, string> = { ...MINIMAL_PARTS };
    const names = [`${segment}.xml`, `${segment}2.xml`];
    for (const name of names) parts[`word/${name}`] = xmlOf(segment);
    parts[SIDECAR] = replaceOnce(
        MINIMAL_PARTS[SIDECAR]!,
        "</Relationships>",
        `${names.map((name, index) => relationship(`rId${index + 2}`, OFFICE(segment), name)).join("")}</Relationships>`,
    );
    parts[CT] = withOverrides(...names.map((name): [string, string] => [`word/${name}`, SINGLETONS[segment]!.ct]));
    return buildDocx(parts);
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s47a: [
        ["s47a-control-minimal", "control", control],
        [
            "styles-custom-styles-own",
            "suffix: rId1 styles→styles.xml, rId3 …/relationships/custom/styles→styles2.xml (styles type)",
            () => suffixSpecimen("styles", OFFICE("custom/styles"), true),
        ],
        [
            "styles-custom-styles-same",
            "suffix: rId1 styles→styles.xml, rId3 …/relationships/custom/styles→styles.xml",
            () => suffixSpecimen("styles", OFFICE("custom/styles"), false),
        ],
        [
            "styles-foreign-styles-own",
            "suffix: rId1 styles→styles.xml, rId3 http://example.com/styles→styles2.xml (styles type)",
            () => suffixSpecimen("styles", "http://example.com/styles", true),
        ],
        [
            "numbering-custom-numbering-own",
            "suffix: rId2 numbering→numbering.xml, rId3 …/relationships/custom/numbering→numbering2.xml",
            () => suffixSpecimen("numbering", OFFICE("custom/numbering"), true),
        ],
        [
            "settings-custom-settings-own",
            "suffix: rId2 settings→settings.xml, rId3 …/relationships/custom/settings→settings2.xml",
            () => suffixSpecimen("settings", OFFICE("custom/settings"), true),
        ],
        [
            "settings-foreign-settings-own",
            "suffix: rId2 settings→settings.xml, rId3 http://example.com/settings→settings2.xml",
            () => suffixSpecimen("settings", "http://example.com/settings", true),
        ],
        ["s47a-control-minimal-end", "control", control],
    ],
    s47b: [
        ["s47b-control-minimal", "control", control],
        [
            "websettings-custom-websettings-own",
            "suffix: rId2 webSettings→webSettings.xml, rId3 …/relationships/custom/webSettings→webSettings2.xml",
            () => suffixSpecimen("webSettings", OFFICE("custom/webSettings"), true),
        ],
        [
            "fonttable-custom-fonttable-own",
            "suffix: rId2 fontTable→fontTable.xml, rId3 …/relationships/custom/fontTable→fontTable2.xml",
            () => suffixSpecimen("fontTable", OFFICE("custom/fontTable"), true),
        ],
        [
            "settings-dup-calibration",
            "calibration (s45f's refused shape): two settings relationships to two parts",
            () => realPair("settings"),
        ],
        ["s47b-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-47 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s47a", "s47b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s47/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-47 parts of docs/plans/evidence/word-probes-2026-10-24.md into s47/section.md.

Reads each chunk's specimens.jsonl (validator columns at f2717ba3, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s47/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s47a", "s47b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s47/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 47: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at f2717ba3",
    "",
    "Does Word count a relationship whose Type only ends in a single-instance segment "
    "([#708](https://github.com/jandira-tech/docx-validate/issues/708), "
    "[#694](https://github.com/jandira-tech/docx-validate/issues/694))? Each chunk ran twice, as two separate "
    "driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, "
    "and `unknown` otherwise; all 13 rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen.",
    "",
    "- Each specimen is the minimal package plus one real relationship of the segment (styles reuses the minimal `rId1`) "
    "and one relationship whose Type only ends in the segment: `…/relationships/custom/<segment>` or "
    "`http://example.com/<segment>`, to its own part typed with the segment's content type, or for styles also to the "
    "real part. Word opens every one clean: it reads `custom/styles`, `custom/numbering`, `custom/settings`, "
    "`custom/webSettings`, `custom/fontTable`, `http://example.com/styles` and `http://example.com/settings` as no "
    "relationship of the segment, as session 27 found for `header`. Word-valid at f2717ba3 rejects the settings, "
    "webSettings and fontTable rows through the suffix-matching duplicate rules (#708, false positives).",
    "- Calibration: two real settings relationships to two parts (session 45's refused shape) get the recovery offer again.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at f2717ba3 | strict at f2717ba3 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 47</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 47 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s47builder.mts", ROOT / "s47builder.mts", "ts"), ("compare.py", ROOT / "s47/compare.py", "python"),
                         ("section.py", ROOT / "s47/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s47/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 48: 10:42Z–10:46Z on 2026-10-26, validator columns at e762ffb5

Does Word read a `wne:toolbarData r:id` whose relationship Type only ends in `attachedToolbars` ([#716](https://github.com/jandira-tech/docx-validate/issues/716))? The chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 8 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- Each specimen is one of the two pinned toolbar fixtures, `tests/fixtures/broken/package.word-attached-toolbar-utf8.docx` (refused bytes in `word/attachedToolbars.bin`) and its twin `tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx` (clean bytes; the two differ only in that part), with the Type of `word/_rels/customizations.xml.rels`'s `rId1`, the relationship `wne:toolbarData r:id` names, replaced by `http://schemas.microsoft.com/office/2006/relationships/custom/attachedToolbars` or `http://example.com/attachedToolbars`. The unchanged fixtures are the calibrations: the broken one gets the recovery offer and the repaired one opens clean, as pinned.
- Word gets the recovery offer for all four retyped specimens, with the clean bytes as with the refused ones: a `wne:toolbarData r:id` naming a relationship whose Type is not exactly the Microsoft `attachedToolbars` Type is refused whatever the target holds. Word-valid at e762ffb5 rejects the two refused-bytes rows through the suffix-matching `word-attached-toolbar-utf8` (the right verdict, for the bytes rather than the Type) and passes the two clean-bytes rows (#716, false negatives).

| Run    | Observed             | Specimen                       | Shape                                                                                                    | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at e762ffb5                | strict at e762ffb5                                                                                                                                                                                                     |
| ------ | -------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s48a` | 10:42:48Z, 10:46:23Z | `s48a-control-minimal`         | control                                                                                                  | `7b643c2f4dc2a37e` | clean-open     | clean-open     | clean-open                 | valid                                 | valid                                                                                                                                                                                                                  |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-refused-calibration`  | calibration: broken/package.word-attached-toolbar-utf8.docx unchanged (refused bytes, real Type)         | `b0cf666af937209d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-attached-toolbar-utf8` | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `word-attached-toolbar-utf8`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-refused-custom-type`  | #716: refused bytes, rId1 Type …/2006/relationships/custom/attachedToolbars                              | `b9f56ddbe3546014` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-attached-toolbar-utf8` | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `word-attached-toolbar-utf8`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-refused-foreign-type` | #716: refused bytes, rId1 Type http://example.com/attachedToolbars                                       | `f5b2323f23f1d0d3` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-attached-toolbar-utf8` | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `word-attached-toolbar-utf8`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-clean-calibration`    | calibration: working/package.word-attached-toolbar-utf8-repaired.docx unchanged (clean bytes, real Type) | `864227204267541a` | clean-open     | clean-open     | clean-open                 | valid                                 | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                               |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-clean-custom-type`    | #716: clean bytes, rId1 Type …/2006/relationships/custom/attachedToolbars                                | `a95c265262f851c4` | repair-warning | repair-warning | unreadable-content-warning | valid                                 | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                               |
| `s48a` | 10:42:48Z, 10:46:23Z | `toolbar-clean-foreign-type`   | #716: clean bytes, rId1 Type http://example.com/attachedToolbars                                         | `5d8400b5158f05f4` | repair-warning | repair-warning | unreadable-content-warning | valid                                 | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                               |
| `s48a` | 10:42:48Z, 10:46:23Z | `s48a-control-minimal-end`     | control                                                                                                  | `0fe06dd45585d12d` | clean-open     | clean-open     | clean-open                 | valid                                 | valid                                                                                                                                                                                                                  |

<details><summary>Raw records, session 48</summary>

```jsonl
{"run": "s48a", "pass": 1, "name": "s48a-control-minimal", "sha256": "7b643c2f4dc2a37ed53fdc721325c376c87af73c2f11596f09cd7ce83504fa5c", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00001__wfv__s48a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s48a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s48a", "pass": 2, "name": "s48a-control-minimal", "sha256": "7b643c2f4dc2a37ed53fdc721325c376c87af73c2f11596f09cd7ce83504fa5c", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00001__wfv__s48a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s48a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s48a", "pass": 1, "name": "toolbar-refused-calibration", "sha256": "b0cf666af937209d4c91305e652eb5216412db6bf83b61aa7c390c59970dc7cb", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00005__wfv__toolbar-refused-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:39:59.775 'Word found unreadable content in 00005__wfv__toolbar-refused-calibration.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:40:00.427 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__toolbar-refused-calibrati...)\""]}
{"run": "s48a", "pass": 2, "name": "toolbar-refused-calibration", "sha256": "b0cf666af937209d4c91305e652eb5216412db6bf83b61aa7c390c59970dc7cb", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00005__wfv__toolbar-refused-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:45:07.525 Microsoft Word, Word found unreadable content in 00005__wfv__toolbar-refused-calibration.docx. Do yo … t? If you trust the source of this document, click Yes.", "2026-10-26 06:45:08.261 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__toolbar-refused-calibrati...)\""]}
{"run": "s48a", "pass": 1, "name": "toolbar-refused-custom-type", "sha256": "b9f56ddbe3546014832a806475582f0221c21aee20ef8c9d3da478b555d1b611", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00006__wfv__toolbar-refused-custom-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:40:08.698 'Word found unreadable content in 00006__wfv__toolbar-refused-custom-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:40:09.641 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__toolbar-refused-custom-ty...)\""]}
{"run": "s48a", "pass": 2, "name": "toolbar-refused-custom-type", "sha256": "b9f56ddbe3546014832a806475582f0221c21aee20ef8c9d3da478b555d1b611", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00006__wfv__toolbar-refused-custom-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:46:07.950 Microsoft Word, Word found unreadable content in 00006__wfv__toolbar-refused-custom-type.docx. Do yo … t? If you trust the source of this document, click Yes.", "2026-10-26 06:46:14.512 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__toolbar-refused-custom-ty...)\""]}
{"run": "s48a", "pass": 1, "name": "toolbar-refused-foreign-type", "sha256": "f5b2323f23f1d0d3c26e313c32d7f5ccdf79212da7ca6ef4889a392d9a868b8f", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00007__wfv__toolbar-refused-foreign-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:42:48.188 'Word found unreadable content in 00007__wfv__toolbar-refused-foreign-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:42:48.786 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__toolbar-refused-foreign-t...)\""]}
{"run": "s48a", "pass": 2, "name": "toolbar-refused-foreign-type", "sha256": "f5b2323f23f1d0d3c26e313c32d7f5ccdf79212da7ca6ef4889a392d9a868b8f", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00007__wfv__toolbar-refused-foreign-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:46:22.848 'Word found unreadable content in 00007__wfv__toolbar-refused-foreign-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:46:23.485 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__toolbar-refused-foreign-t...)\""]}
{"run": "s48a", "pass": 1, "name": "toolbar-clean-calibration", "sha256": "864227204267541a0ecabc3a72412ec3b19b38b9541d3fd84e6f7916e1dd1c68", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00002__wfv__toolbar-clean-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s48a", "pass": 2, "name": "toolbar-clean-calibration", "sha256": "864227204267541a0ecabc3a72412ec3b19b38b9541d3fd84e6f7916e1dd1c68", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00002__wfv__toolbar-clean-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s48a", "pass": 1, "name": "toolbar-clean-custom-type", "sha256": "a95c265262f851c427b94db781965452ebeda23780223d4681dbeabdb8c119da", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00003__wfv__toolbar-clean-custom-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:35:27.061 'Word found unreadable content in 00003__wfv__toolbar-clean-custom-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:35:33.170 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__toolbar-clean-custom-type...)\""]}
{"run": "s48a", "pass": 2, "name": "toolbar-clean-custom-type", "sha256": "a95c265262f851c427b94db781965452ebeda23780223d4681dbeabdb8c119da", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00003__wfv__toolbar-clean-custom-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:43:20.444 'Word found unreadable content in 00003__wfv__toolbar-clean-custom-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:43:21.119 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__toolbar-clean-custom-type...)\""]}
{"run": "s48a", "pass": 1, "name": "toolbar-clean-foreign-type", "sha256": "5d8400b5158f05f4abf02a5c993ad42cd0b80146781613ad35f2c76ca0286ead", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00004__wfv__toolbar-clean-foreign-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:36:29.951 Microsoft Word, Word found unreadable content in 00004__wfv__toolbar-clean-foreign-type.docx. Do you … t? If you trust the source of this document, click Yes."]}
{"run": "s48a", "pass": 2, "name": "toolbar-clean-foreign-type", "sha256": "5d8400b5158f05f4abf02a5c993ad42cd0b80146781613ad35f2c76ca0286ead", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00004__wfv__toolbar-clean-foreign-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:44:13.156 Microsoft Word, Word found unreadable content in 00004__wfv__toolbar-clean-foreign-type.docx. Do you … t? If you trust the source of this document, click Yes."]}
{"run": "s48a", "pass": 1, "name": "s48a-control-minimal-end", "sha256": "0fe06dd45585d12d12c838c07b884340b386c6956bf75ce9399b87eefe1bb221", "observedAt": "2026-10-26T10:42:48+00:00", "staged": "00000__wfv__s48a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s48a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s48a", "pass": 2, "name": "s48a-control-minimal-end", "sha256": "0fe06dd45585d12d12c838c07b884340b386c6956bf75ce9399b87eefe1bb221", "observedAt": "2026-10-26T10:46:23+00:00", "staged": "00000__wfv__s48a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s48a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 48 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s48builder.mts`:

```ts
// Session 48 (2026-10-26): does Word read a `wne:toolbarData r:id` whose relationship Type only ENDS in
// `attachedToolbars`? `word-attached-toolbar-utf8` accepts the toolbar relationship by `type.endsWith("/attachedToolbars")`
// and blocks word-valid when the target's bytes hold the refused sequence (#716). Word reads relationship Types
// exactly elsewhere (sessions 27 and 47). Each specimen is one of the pinned toolbar fixtures — the refused
// `broken/package.word-attached-toolbar-utf8.docx` and its clean twin `working/…-repaired.docx`, which differ only in
// `word/attachedToolbars.bin` — with the Type of `word/_rels/customizations.xml.rels`'s rId1 replaced; the two
// fixtures themselves are the calibrations.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s48a pnpm exec tsx s48builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const BROKEN = "tests/fixtures/broken/package.word-attached-toolbar-utf8.docx";
const WORKING = "tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx";
const RELS = "word/_rels/customizations.xml.rels";
const REAL = "http://schemas.microsoft.com/office/2006/relationships/attachedToolbars";
const CUSTOM = "http://schemas.microsoft.com/office/2006/relationships/custom/attachedToolbars";
const FOREIGN = "http://example.com/attachedToolbars";

const control = () => buildDocx({ ...MINIMAL_PARTS });
const fixture = async (file: string) => new Uint8Array(readFileSync(file));
/** The fixture with rId1's Type in the customizations sidecar replaced by `type`; every other entry unchanged. */
const retyped = async (file: string, type: string) => {
    const zip = await JSZip.loadAsync(readFileSync(file));
    const rels = await zip.file(RELS)!.async("string");
    if (rels.split(`Type="${REAL}"`).length !== 2) throw new Error(`expected exactly one ${REAL} in ${RELS}`);
    zip.file(RELS, rels.replace(`Type="${REAL}"`, `Type="${type}"`));
    return zip.generateAsync({ type: "uint8array", compression: "DEFLATE" });
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s48a: [
        ["s48a-control-minimal", "control", control],
        [
            "toolbar-refused-calibration",
            "calibration: broken/package.word-attached-toolbar-utf8.docx unchanged (refused bytes, real Type)",
            () => fixture(BROKEN),
        ],
        [
            "toolbar-refused-custom-type",
            "#716: refused bytes, rId1 Type …/2006/relationships/custom/attachedToolbars",
            () => retyped(BROKEN, CUSTOM),
        ],
        [
            "toolbar-refused-foreign-type",
            "#716: refused bytes, rId1 Type http://example.com/attachedToolbars",
            () => retyped(BROKEN, FOREIGN),
        ],
        [
            "toolbar-clean-calibration",
            "calibration: working/package.word-attached-toolbar-utf8-repaired.docx unchanged (clean bytes, real Type)",
            () => fixture(WORKING),
        ],
        [
            "toolbar-clean-custom-type",
            "#716: clean bytes, rId1 Type …/2006/relationships/custom/attachedToolbars",
            () => retyped(WORKING, CUSTOM),
        ],
        ["toolbar-clean-foreign-type", "#716: clean bytes, rId1 Type http://example.com/attachedToolbars", () => retyped(WORKING, FOREIGN)],
        ["s48a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-48 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s48a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s48/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-48 parts of docs/plans/evidence/word-probes-2026-10-24.md into s48/section.md.

Reads the chunk's specimens.jsonl (validator columns at e762ffb5, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s48/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s48a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s48/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 48: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at e762ffb5",
    "",
    "Does Word read a `wne:toolbarData r:id` whose relationship Type only ends in `attachedToolbars` "
    "([#716](https://github.com/jandira-tech/docx-validate/issues/716))? The chunk ran twice, as two separate "
    "driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, "
    "and `unknown` otherwise; all 8 rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen.",
    "",
    "- Each specimen is one of the two pinned toolbar fixtures, `tests/fixtures/broken/package.word-attached-toolbar-utf8.docx` "
    "(refused bytes in `word/attachedToolbars.bin`) and its twin `tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx` "
    "(clean bytes; the two differ only in that part), with the Type of `word/_rels/customizations.xml.rels`'s `rId1`, the "
    "relationship `wne:toolbarData r:id` names, replaced by `http://schemas.microsoft.com/office/2006/relationships/custom/attachedToolbars` "
    "or `http://example.com/attachedToolbars`. The unchanged fixtures are the calibrations: the broken one gets the recovery "
    "offer and the repaired one opens clean, as pinned.",
    "- Word gets the recovery offer for all four retyped specimens, with the clean bytes as with the refused ones: a "
    "`wne:toolbarData r:id` naming a relationship whose Type is not exactly the Microsoft `attachedToolbars` Type is "
    "refused whatever the target holds. Word-valid at e762ffb5 rejects the two refused-bytes rows through the "
    "suffix-matching `word-attached-toolbar-utf8` (the right verdict, for the bytes rather than the Type) and passes "
    "the two clean-bytes rows (#716, false negatives).",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at e762ffb5 | strict at e762ffb5 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 48</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 48 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s48builder.mts", ROOT / "s48builder.mts", "ts"), ("compare.py", ROOT / "s48/compare.py", "python"),
                         ("section.py", ROOT / "s48/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s48/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 49: 10:51Z–11:05Z on 2026-10-26, validator columns at e762ffb5

The shapes the adversarial review of layers 145 ([#707](https://github.com/jandira-tech/docx-validate/issues/707)) and 146 ([#694](https://github.com/jandira-tech/docx-validate/issues/694)) said those layers judge without evidence. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 20 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- `s49a`, #707: the minimal package with `word/styles.xml` (styles XML) typed by its Override as `application/octet-stream` (session 46 showed only the Default spelling, on `word/styles.bin`), `APPLICATION/OCTET-STREAM`, `application/octet-stream; charset=utf-8`, `image/png` or `application/foo+xml`: Word gets the recovery offer for every one. Word-valid rejects all five through `word-part-content-type-unrecognized`.
- `s49b`, #707: an empty `ContentType=""` on the styles Override, the main document's Override typed `application/octet-stream`, and the styles Override typed with the settings content type: Word gets the recovery offer for all three, and word-valid passes all three (false negatives).
- `s49c`, #694: two more styles relationships in `_rels/.rels`, and two in the sidecar of a header the body references, open clean; word-valid rejects both through `word-duplicate-styles-relationship` (false positives). Two styles relationships in a reached glossary's sidecar get the recovery offer, as session 45's calibration in the main document's sidecar does again. The main document's real styles relationship beside one or two External styles relationships gets the recovery offer; word-valid rejects both.

| Run    | Observed             | Specimen                        | Shape                                                                                                | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at e762ffb5                         | strict at e762ffb5                                                      |
| ------ | -------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------- |
| `s49a` | 10:51:16Z, 10:56:30Z | `s49a-control-minimal`          | control                                                                                              | `bc836a78db359af5` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |
| `s49a` | 10:51:16Z, 10:56:30Z | `styles-override-octet`         | #707 F1: word/styles.xml (styles XML) Override typed application/octet-stream                        | `e8b2274afdd14cc5` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized`                          |
| `s49a` | 10:51:16Z, 10:56:30Z | `styles-override-octet-upper`   | #707 F1: styles Override typed APPLICATION/OCTET-STREAM                                              | `d402d5539394305d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized`                          |
| `s49a` | 10:51:16Z, 10:56:30Z | `styles-override-octet-charset` | #707 F1: styles Override typed application/octet-stream; charset=utf-8                               | `b64d41a96560e7fb` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized`                          |
| `s49a` | 10:51:16Z, 10:56:30Z | `styles-override-image-png`     | #707 F1: styles Override typed image/png                                                             | `e0426cec1d1b3231` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized`                          |
| `s49a` | 10:51:16Z, 10:56:30Z | `styles-override-foo-xml`       | #707 F1: styles Override typed application/foo+xml                                                   | `979612c08fbbbebf` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized`                          |
| `s49a` | 10:51:16Z, 10:56:30Z | `s49a-control-minimal-end`      | control                                                                                              | `53f175096f85436b` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |
| `s49b` | 10:58:42Z, 11:00:18Z | `s49b-control-minimal`          | control                                                                                              | `54be6142d8cfa1a4` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |
| `s49b` | 10:58:42Z, 11:00:18Z | `styles-override-empty`         | #707 F6: styles Override ContentType=""                                                              | `868b339eb3e2e5ef` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `xsd-summary`, `xsd-error`                                     |
| `s49b` | 10:58:42Z, 11:00:18Z | `main-override-octet`           | #707 F7: main document Override typed application/octet-stream                                       | `facffeeae4356948` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-unrecognized`                          |
| `s49b` | 10:58:42Z, 11:00:18Z | `styles-override-settings-type` | #707 F8: styles Override typed with the settings content type                                        | `c3319b7315c01185` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`                              |
| `s49b` | 10:58:42Z, 11:00:18Z | `s49b-control-minimal-end`      | control                                                                                              | `54be6142d8cfa1a4` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |
| `s49c` | 11:02:17Z, 11:05:12Z | `s49c-control-minimal`          | control                                                                                              | `d5316e712ead77ab` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |
| `s49c` | 11:02:17Z, 11:05:12Z | `dup-styles-main-calibration`   | calibration (s45's refused shape): two internal styles relationships in word/_rels/document.xml.rels | `7db93e23087578a7` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-styles-relationship`  | invalid: `word-duplicate-styles-relationship`                           |
| `s49c` | 11:02:17Z, 11:05:12Z | `dup-styles-package-rels`       | #694 F3: _rels/.rels adds two styles relationships (word/styles.xml, word/styles2.xml)               | `0cfdd623ac1524f8` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-styles-relationship`  | invalid: `word-duplicate-styles-relationship`                           |
| `s49c` | 11:02:17Z, 11:05:12Z | `dup-styles-header-sidecar`     | #694 F3: a referenced header's sidecar holds two styles relationships                                | `4f83912998c7853a` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-styles-relationship`  | invalid: `paraid-missing-element`, `word-duplicate-styles-relationship` |
| `s49c` | 11:02:17Z, 11:05:12Z | `dup-styles-glossary-sidecar`   | #694 F3: a reached glossary's sidecar holds two styles relationships to two parts                    | `3fbc96bb8e28909e` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-styles-relationship`  | invalid: `paraid-missing-element`, `word-duplicate-styles-relationship` |
| `s49c` | 11:02:17Z, 11:05:12Z | `styles-plus-one-external`      | #694 F4: the real styles relationship plus one External styles relationship                          | `59e452a93f1b2a70` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-styles-relationship`  | invalid: `word-duplicate-styles-relationship`                           |
| `s49c` | 11:02:17Z, 11:05:12Z | `styles-plus-two-external`      | #694 F4: the real styles relationship plus two External styles relationships                         | `5600dca9281d6709` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-styles-relationship`  | invalid: `word-duplicate-styles-relationship`                           |
| `s49c` | 11:02:17Z, 11:05:12Z | `s49c-control-minimal-end`      | control                                                                                              | `d5316e712ead77ab` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                                                   |

<details><summary>Raw records, session 49</summary>

```jsonl
{"run": "s49a", "pass": 1, "name": "s49a-control-minimal", "sha256": "bc836a78db359af57775d751340ca466dd6d7d3a2281231fd849018d02ea0027", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00001__wfv__s49a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49a", "pass": 2, "name": "s49a-control-minimal", "sha256": "bc836a78db359af57775d751340ca466dd6d7d3a2281231fd849018d02ea0027", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00001__wfv__s49a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49a", "pass": 1, "name": "styles-override-octet", "sha256": "e8b2274afdd14cc548370acc2c5bd1b3d833b1aed6fb93fb3560b3f16e74fd1a", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00006__wfv__styles-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:51:15.806 'Word found unreadable content in 00006__wfv__styles-override-octet.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:51:16.319 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__styles-override-octet.docx)\""]}
{"run": "s49a", "pass": 2, "name": "styles-override-octet", "sha256": "e8b2274afdd14cc548370acc2c5bd1b3d833b1aed6fb93fb3560b3f16e74fd1a", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00006__wfv__styles-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:56:30.232 'Word found unreadable content in 00006__wfv__styles-override-octet.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:56:30.721 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__styles-override-octet.docx)\""]}
{"run": "s49a", "pass": 1, "name": "styles-override-octet-upper", "sha256": "d402d5539394305d8f5d6a7a43a01ace6c809e56ca72c644c567c03fe9bbc216", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00005__wfv__styles-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:51:11.630 'Word found unreadable content in 00005__wfv__styles-override-octet-upper.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:51:12.468 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-override-octet-upp...)\""]}
{"run": "s49a", "pass": 2, "name": "styles-override-octet-upper", "sha256": "d402d5539394305d8f5d6a7a43a01ace6c809e56ca72c644c567c03fe9bbc216", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00005__wfv__styles-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:55:38.727 Microsoft Word, Word found unreadable content in 00005__wfv__styles-override-octet-upper.docx. Do yo … t? If you trust the source of this document, click Yes.", "2026-10-26 06:55:39.415 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-override-octet-upp...)\""]}
{"run": "s49a", "pass": 1, "name": "styles-override-octet-charset", "sha256": "b64d41a96560e7fb205212e196ba6fedf9da8f3c73c79da41c1fd274991c7c2e", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00004__wfv__styles-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:51:07.493 'Word found unreadable content in 00004__wfv__styles-override-octet-charset.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:51:08.020 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-override-octet-cha...)\""]}
{"run": "s49a", "pass": 2, "name": "styles-override-octet-charset", "sha256": "b64d41a96560e7fb205212e196ba6fedf9da8f3c73c79da41c1fd274991c7c2e", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00004__wfv__styles-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:54:50.384 \"Word found unreadable content in 00004__wfv__styles-override-octet-charset.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49a", "pass": 1, "name": "styles-override-image-png", "sha256": "e0426cec1d1b3231c821c3b850537d914316a59adec8302fdf14a60b07e1309a", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00003__wfv__styles-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:50:14.755 Microsoft Word, Word found unreadable content in 00003__wfv__styles-override-image-png.docx. Do you  … t? If you trust the source of this document, click Yes."]}
{"run": "s49a", "pass": 2, "name": "styles-override-image-png", "sha256": "e0426cec1d1b3231c821c3b850537d914316a59adec8302fdf14a60b07e1309a", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00003__wfv__styles-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:52:40.223 Microsoft Word, Word found unreadable content in 00003__wfv__styles-override-image-png.docx. Do you  … t? If you trust the source of this document, click Yes."]}
{"run": "s49a", "pass": 1, "name": "styles-override-foo-xml", "sha256": "979612c08fbbbebf31e49ce9b05a2af98250ec72c4df1679a3e547fe1cfe45d0", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00002__wfv__styles-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:49:20.665 'Word found unreadable content in 00002__wfv__styles-override-foo-xml.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:49:21.373 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-override-foo-xml.docx)\""]}
{"run": "s49a", "pass": 2, "name": "styles-override-foo-xml", "sha256": "979612c08fbbbebf31e49ce9b05a2af98250ec72c4df1679a3e547fe1cfe45d0", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00002__wfv__styles-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:51:47.215 'Word found unreadable content in 00002__wfv__styles-override-foo-xml.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:51:48.124 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-override-foo-xml.docx)\""]}
{"run": "s49a", "pass": 1, "name": "s49a-control-minimal-end", "sha256": "53f175096f85436b786fa0c25216e7359e5270cf0679e2d5c7edd265e7291109", "observedAt": "2026-10-26T10:51:16+00:00", "staged": "00000__wfv__s49a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49a", "pass": 2, "name": "s49a-control-minimal-end", "sha256": "53f175096f85436b786fa0c25216e7359e5270cf0679e2d5c7edd265e7291109", "observedAt": "2026-10-26T10:56:30+00:00", "staged": "00000__wfv__s49a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49b", "pass": 1, "name": "s49b-control-minimal", "sha256": "54be6142d8cfa1a4e489b08dab17ae2b0438135dc2359696218e163896bdc7a7", "observedAt": "2026-10-26T10:58:42+00:00", "staged": "00002__wfv__s49b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49b", "pass": 2, "name": "s49b-control-minimal", "sha256": "54be6142d8cfa1a4e489b08dab17ae2b0438135dc2359696218e163896bdc7a7", "observedAt": "2026-10-26T11:00:18+00:00", "staged": "00002__wfv__s49b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49b", "pass": 1, "name": "styles-override-empty", "sha256": "868b339eb3e2e5ef9a475c332bc70e17a75d9853f1195c4f8dcc14ad373c9b9b", "observedAt": "2026-10-26T10:58:42+00:00", "staged": "00003__wfv__styles-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:57:11.634 \"Word found unreadable content in 00003__wfv__styles-override-empty.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49b", "pass": 2, "name": "styles-override-empty", "sha256": "868b339eb3e2e5ef9a475c332bc70e17a75d9853f1195c4f8dcc14ad373c9b9b", "observedAt": "2026-10-26T11:00:18+00:00", "staged": "00003__wfv__styles-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:59:18.832 \"Word found unreadable content in 00003__wfv__styles-override-empty.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49b", "pass": 1, "name": "main-override-octet", "sha256": "facffeeae435694874be44c9c28eb19c2d3d771a9fcf0551e6180121c08ce896", "observedAt": "2026-10-26T10:58:42+00:00", "staged": "00000__wfv__main-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:56:52.701 'Word found unreadable content in 00000__wfv__main-override-octet.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:56:53.268 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00000__wfv__main-override-octet.docx)\""]}
{"run": "s49b", "pass": 2, "name": "main-override-octet", "sha256": "facffeeae435694874be44c9c28eb19c2d3d771a9fcf0551e6180121c08ce896", "observedAt": "2026-10-26T11:00:18+00:00", "staged": "00000__wfv__main-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:59:01.465 'Word found unreadable content in 00000__wfv__main-override-octet.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-26 06:59:02.033 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00000__wfv__main-override-octet.docx)\""]}
{"run": "s49b", "pass": 1, "name": "styles-override-settings-type", "sha256": "c3319b7315c01185d8d781cc6b1c2e189e2c994213d312bc70773204dc973517", "observedAt": "2026-10-26T10:58:42+00:00", "staged": "00004__wfv__styles-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 06:58:41.734 'Word found unreadable content in 00004__wfv__styles-override-settings-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'"]}
{"run": "s49b", "pass": 2, "name": "styles-override-settings-type", "sha256": "c3319b7315c01185d8d781cc6b1c2e189e2c994213d312bc70773204dc973517", "observedAt": "2026-10-26T11:00:18+00:00", "staged": "00004__wfv__styles-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:00:10.462 Microsoft Word, Word found unreadable content in 00004__wfv__styles-override-settings-type.docx. Do  … t? If you trust the source of this document, click Yes."]}
{"run": "s49b", "pass": 1, "name": "s49b-control-minimal-end", "sha256": "54be6142d8cfa1a4e489b08dab17ae2b0438135dc2359696218e163896bdc7a7", "observedAt": "2026-10-26T10:58:42+00:00", "staged": "00001__wfv__s49b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49b", "pass": 2, "name": "s49b-control-minimal-end", "sha256": "54be6142d8cfa1a4e489b08dab17ae2b0438135dc2359696218e163896bdc7a7", "observedAt": "2026-10-26T11:00:18+00:00", "staged": "00001__wfv__s49b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 1, "name": "s49c-control-minimal", "sha256": "d5316e712ead77abe5163bbda02d6207319e957d283cac33addc6ea4e963d1c5", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00005__wfv__s49c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 2, "name": "s49c-control-minimal", "sha256": "d5316e712ead77abe5163bbda02d6207319e957d283cac33addc6ea4e963d1c5", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00005__wfv__s49c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 1, "name": "dup-styles-main-calibration", "sha256": "7db93e23087578a7c0c879d17e76b5e412e268eaf302c570585871d3ed22c59e", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00002__wfv__dup-styles-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:00:58.432 \"Word found unreadable content in 00002__wfv__dup-styles-main-calibration.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49c", "pass": 2, "name": "dup-styles-main-calibration", "sha256": "7db93e23087578a7c0c879d17e76b5e412e268eaf302c570585871d3ed22c59e", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00002__wfv__dup-styles-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:02:54.771 \"Word found unreadable content in 00002__wfv__dup-styles-main-calibration.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49c", "pass": 1, "name": "dup-styles-package-rels", "sha256": "0cfdd623ac1524f8962fbf970e9f831d8c7d607ea6b8685db409863a8ccda018", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00003__wfv__dup-styles-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-styles-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 2, "name": "dup-styles-package-rels", "sha256": "0cfdd623ac1524f8962fbf970e9f831d8c7d607ea6b8685db409863a8ccda018", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00003__wfv__dup-styles-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-styles-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 1, "name": "dup-styles-header-sidecar", "sha256": "4f83912998c7853a67f925d6bedf13fb47cc1f5d42fd268dcd000fa53c016dc5", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00001__wfv__dup-styles-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-styles-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 2, "name": "dup-styles-header-sidecar", "sha256": "4f83912998c7853a67f925d6bedf13fb47cc1f5d42fd268dcd000fa53c016dc5", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00001__wfv__dup-styles-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-styles-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 1, "name": "dup-styles-glossary-sidecar", "sha256": "3fbc96bb8e28909e464ab22cf1a05317361b785cdc9089c6666c9a9abad54e93", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00000__wfv__dup-styles-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:00:41.032 'Word found unreadable content in 00000__wfv__dup-styles-glossary-sidecar.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:00:41.616 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-styles-glossary-sidec...)\""]}
{"run": "s49c", "pass": 2, "name": "dup-styles-glossary-sidecar", "sha256": "3fbc96bb8e28909e464ab22cf1a05317361b785cdc9089c6666c9a9abad54e93", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00000__wfv__dup-styles-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:02:38.884 'Word found unreadable content in 00000__wfv__dup-styles-glossary-sidecar.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:02:39.533 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-styles-glossary-sidec...)\""]}
{"run": "s49c", "pass": 1, "name": "styles-plus-one-external", "sha256": "59e452a93f1b2a70ed51baae841b1cef5b2386f1d9b59b3e17f1d428ac59efcf", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00006__wfv__styles-plus-one-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:01:14.166 \"Word found unreadable content in 00006__wfv__styles-plus-one-external.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49c", "pass": 2, "name": "styles-plus-one-external", "sha256": "59e452a93f1b2a70ed51baae841b1cef5b2386f1d9b59b3e17f1d428ac59efcf", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00006__wfv__styles-plus-one-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:03:09.336 \"Word found unreadable content in 00006__wfv__styles-plus-one-external.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49c", "pass": 1, "name": "styles-plus-two-external", "sha256": "5600dca9281d67098f2fa9af3c723a09dc5646a54c3d020bc8be5b091ddf9296", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00007__wfv__styles-plus-two-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:02:16.465 'Word found unreadable content in 00007__wfv__styles-plus-two-external.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:02:17.004 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-plus-two-external....)\""]}
{"run": "s49c", "pass": 2, "name": "styles-plus-two-external", "sha256": "5600dca9281d67098f2fa9af3c723a09dc5646a54c3d020bc8be5b091ddf9296", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00007__wfv__styles-plus-two-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:05:12.591 \"Word found unreadable content in 00007__wfv__styles-plus-two-external.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s49c", "pass": 1, "name": "s49c-control-minimal-end", "sha256": "d5316e712ead77abe5163bbda02d6207319e957d283cac33addc6ea4e963d1c5", "observedAt": "2026-10-26T11:02:17+00:00", "staged": "00004__wfv__s49c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s49c", "pass": 2, "name": "s49c-control-minimal-end", "sha256": "d5316e712ead77abe5163bbda02d6207319e957d283cac33addc6ea4e963d1c5", "observedAt": "2026-10-26T11:05:12+00:00", "staged": "00004__wfv__s49c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s49c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 49 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s49builder.mts`:

```ts
// Session 49 (2026-10-26): the shapes review 145-146 says layers 145 (#707) and 146 (#694) judge without evidence.
// - s49a: session 46 saw Word refuse a styles part typed `application/octet-stream` by a Default (`word/styles.bin`).
//   `word-part-content-type-unrecognized` claims the recovery offer for any unrecognised type on the main styles reach
//   (review finding 1). Here `word/styles.xml` keeps its XML and its Override carries the type: octet-stream itself (the
//   Override spelling session 46 did not show), upper case, with a parameter, `image/png` and `application/foo+xml`.
// - s49b: an empty `ContentType=""` on the styles Override (finding 6), the main document's Override typed
//   `application/octet-stream` (finding 7) and the styles Override typed with the settings type (finding 8's hole).
// - s49c: two styles relationships outside the main document's relationships part, in `_rels/.rels`, a reached header's
//   sidecar and a reached glossary's sidecar (finding 3), and one real styles relationship beside an External one
//   (finding 4). Session 45 refused two internal styles relationships in `word/_rels/document.xml.rels` only.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s49a pnpm exec tsx s49builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const STYLES_TYPE = `${WML}.styles+xml`;
const MAIN_TYPE = `${WML}.document.main+xml`;
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, external = false) =>
    `<Relationship Id="${id}" Type="${REL}/${segment}" Target="${target}"${external ? ' TargetMode="External"' : ""}/>`;
const relsPart = (body: string) =>
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const mainRels = (extra: string) => replaceOnce(P[SIDECAR]!, "</Relationships>", `${extra}</Relationships>`);
const withOverrides = (...overrides: Array<[string, string]>) =>
    replaceOnce(
        P[CT]!,
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/** The minimal package with the Override of `part` carrying `type` instead of its own. */
const retypedOverride = (part: string, own: string, type: string) =>
    buildDocx({
        ...P,
        [CT]: replaceOnce(
            P[CT]!,
            `<Override PartName="/${part}" ContentType="${own}"/>`,
            `<Override PartName="/${part}" ContentType="${type}"/>`,
        ),
    });
const stylesTyped = (type: string) => retypedOverride("word/styles.xml", STYLES_TYPE, type);

const STYLES2: Record<string, string> = { "word/styles2.xml": P["word/styles.xml"]! };
/** Two more styles relationships in the package relationships part, beside the main document's own. */
const dupInPackageRels = () =>
    buildDocx({
        ...P,
        ...STYLES2,
        "_rels/.rels": replaceOnce(
            P["_rels/.rels"]!,
            "</Relationships>",
            `${relationship("rId8", "styles", "word/styles.xml")}${relationship("rId9", "styles", "word/styles2.xml")}</Relationships>`,
        ),
        [CT]: withOverrides(["word/styles2.xml", STYLES_TYPE]),
    });
const HEADER = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
/** A header the body section references, its own sidecar holding two styles relationships. */
const dupInHeaderRels = () =>
    buildDocx({
        ...P,
        ...STYLES2,
        "word/document.xml": replaceOnce(
            replaceOnce(P["word/document.xml"]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:sectPr>",
            `<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>`,
        ),
        "word/header9.xml": HEADER,
        "word/_rels/header9.xml.rels": relsPart(
            `${relationship("rId1", "styles", "styles.xml")}${relationship("rId2", "styles", "styles2.xml")}`,
        ),
        [SIDECAR]: mainRels(relationship("rIdH", "header", "header9.xml")),
        [CT]: withOverrides(["word/header9.xml", `${WML}.header+xml`], ["word/styles2.xml", STYLES_TYPE]),
    });
const GLOSSARY =
    `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/** A reached glossary whose own sidecar holds two styles relationships to two parts. */
const dupInGlossaryRels = () =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        "word/glossary/styles.xml": P["word/styles.xml"]!,
        "word/glossary/styles2.xml": P["word/styles.xml"]!,
        "word/glossary/_rels/document.xml.rels": relsPart(
            `${relationship("rId1", "styles", "styles.xml")}${relationship("rId2", "styles", "styles2.xml")}`,
        ),
        [SIDECAR]: mainRels(relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
        [CT]: withOverrides(
            ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
            ["word/glossary/styles.xml", STYLES_TYPE],
            ["word/glossary/styles2.xml", STYLES_TYPE],
        ),
    });
/** The main document's real styles relationship beside `count` External ones. */
const withExternalStyles = (count: number) =>
    buildDocx({
        ...P,
        [SIDECAR]: mainRels(
            Array.from({ length: count }, (_, i) =>
                relationship(`rIdX${i + 1}`, "styles", `http://example.com/styles${i + 1}.xml`, true),
            ).join(""),
        ),
    });
/** Session 45's refused shape again, as the chunk's calibration: two internal styles relationships to two parts. */
const dupInMainRels = () =>
    buildDocx({
        ...P,
        ...STYLES2,
        [SIDECAR]: mainRels(relationship("rId9", "styles", "styles2.xml")),
        [CT]: withOverrides(["word/styles2.xml", STYLES_TYPE]),
    });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s49a: [
        ["s49a-control-minimal", "control", control],
        [
            "styles-override-octet",
            "#707 F1: word/styles.xml (styles XML) Override typed application/octet-stream",
            () => stylesTyped("application/octet-stream"),
        ],
        [
            "styles-override-octet-upper",
            "#707 F1: styles Override typed APPLICATION/OCTET-STREAM",
            () => stylesTyped("APPLICATION/OCTET-STREAM"),
        ],
        [
            "styles-override-octet-charset",
            "#707 F1: styles Override typed application/octet-stream; charset=utf-8",
            () => stylesTyped("application/octet-stream; charset=utf-8"),
        ],
        ["styles-override-image-png", "#707 F1: styles Override typed image/png", () => stylesTyped("image/png")],
        ["styles-override-foo-xml", "#707 F1: styles Override typed application/foo+xml", () => stylesTyped("application/foo+xml")],
        ["s49a-control-minimal-end", "control", control],
    ],
    s49b: [
        ["s49b-control-minimal", "control", control],
        ["styles-override-empty", '#707 F6: styles Override ContentType=""', () => stylesTyped("")],
        [
            "main-override-octet",
            "#707 F7: main document Override typed application/octet-stream",
            () => retypedOverride("word/document.xml", MAIN_TYPE, "application/octet-stream"),
        ],
        [
            "styles-override-settings-type",
            "#707 F8: styles Override typed with the settings content type",
            () => stylesTyped(`${WML}.settings+xml`),
        ],
        ["s49b-control-minimal-end", "control", control],
    ],
    s49c: [
        ["s49c-control-minimal", "control", control],
        [
            "dup-styles-main-calibration",
            "calibration (s45's refused shape): two internal styles relationships in word/_rels/document.xml.rels",
            dupInMainRels,
        ],
        [
            "dup-styles-package-rels",
            "#694 F3: _rels/.rels adds two styles relationships (word/styles.xml, word/styles2.xml)",
            dupInPackageRels,
        ],
        ["dup-styles-header-sidecar", "#694 F3: a referenced header's sidecar holds two styles relationships", dupInHeaderRels],
        [
            "dup-styles-glossary-sidecar",
            "#694 F3: a reached glossary's sidecar holds two styles relationships to two parts",
            dupInGlossaryRels,
        ],
        [
            "styles-plus-one-external",
            "#694 F4: the real styles relationship plus one External styles relationship",
            () => withExternalStyles(1),
        ],
        [
            "styles-plus-two-external",
            "#694 F4: the real styles relationship plus two External styles relationships",
            () => withExternalStyles(2),
        ],
        ["s49c-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-49 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s49a", "s49b", "s49c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s49/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-49 parts of docs/plans/evidence/word-probes-2026-10-24.md into s49/section.md.

Reads the chunk's specimens.jsonl (validator columns at e762ffb5, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s49/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s49a", "s49b", "s49c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s49/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 49: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at e762ffb5",
    "",
    "The shapes the adversarial review of layers 145 ([#707](https://github.com/jandira-tech/docx-validate/issues/707)) and "
    "146 ([#694](https://github.com/jandira-tech/docx-validate/issues/694)) said those layers judge without evidence. Each chunk ran "
    "twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log "
    "(session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings "
    "agree, and `unknown` otherwise; all 20 rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen.",
    "",
    "- `s49a`, #707: the minimal package with `word/styles.xml` (styles XML) typed by its Override as `application/octet-stream` "
    "(session 46 showed only the Default spelling, on `word/styles.bin`), `APPLICATION/OCTET-STREAM`, "
    "`application/octet-stream; charset=utf-8`, `image/png` or `application/foo+xml`: Word gets the recovery offer for every one. "
    "Word-valid rejects all five through `word-part-content-type-unrecognized`.",
    "- `s49b`, #707: an empty `ContentType=\"\"` on the styles Override, the main document's Override typed `application/octet-stream`, "
    "and the styles Override typed with the settings content type: Word gets the recovery offer for all three, and word-valid "
    "passes all three (false negatives).",
    "- `s49c`, #694: two more styles relationships in `_rels/.rels`, and two in the sidecar of a header the body references, open "
    "clean; word-valid rejects both through `word-duplicate-styles-relationship` (false positives). Two styles relationships in a "
    "reached glossary's sidecar get the recovery offer, as session 45's calibration in the main document's sidecar does again. The "
    "main document's real styles relationship beside one or two External styles relationships gets the recovery offer; word-valid "
    "rejects both.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at e762ffb5 | strict at e762ffb5 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 49</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 49 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s49builder.mts", ROOT / "s49builder.mts", "ts"), ("compare.py", ROOT / "s49/compare.py", "python"),
                         ("section.py", ROOT / "s49/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s49/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 50: 11:26Z–11:40Z on 2026-10-26, validator columns at 01e4e684

The scope the session 49 follow-ups need: where Word refuses duplicate relationships ([#717](https://github.com/jandira-tech/docx-validate/issues/717)), and which content types it refuses on the main document and the other parts it relates ([#720](https://github.com/jandira-tech/docx-validate/issues/720), [#721](https://github.com/jandira-tech/docx-validate/issues/721), [#722](https://github.com/jandira-tech/docx-validate/issues/722)). Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 32 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The part bodies are session 47's empty roots; the theme part is `word/theme/theme1.xml` of `tests/fixtures/working/package.drawing-arc-radius-integer.docx` (clean-open in the manifest).

- `s50a` and `s50b`, #717: two relationships of one kind outside the main document's relationships part. In `_rels/.rels` (beside the main document's own relationship of the kind) two numbering, settings or theme relationships open clean, as styles did in session 49; in the sidecar of a header the body references, two numbering, settings, fontTable, webSettings or theme relationships open clean. In a reached glossary's sidecar, two numbering, settings or fontTable relationships to two parts get the recovery offer, as styles did; so does session 45's numbering calibration in `word/_rels/document.xml.rels`. Word-valid rejects every one of them, so the eight clean rows are false positives.
- `s50c`, #721 and #720: the main document's Override typed `APPLICATION/OCTET-STREAM`, `application/octet-stream; charset=utf-8`, `image/png` or `application/foo+xml`, and an empty `ContentType=""` on the Override of a related settings or fontTable part, get the recovery offer; word-valid passes all six (false negatives).
- `s50d`, #722 and review finding 1: a related settings, fontTable or numbering part typed `application/octet-stream`, settings typed with the styles content type, numbering with the settings content type, and the main document with the styles content type get the recovery offer; word-valid passes all six (false negatives).

| Run    | Observed             | Specimen                           | Shape                                                                                                 | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 01e4e684                              | strict at 01e4e684                                                            |
| ------ | -------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------- |
| `s50a` | 11:26:39Z, 11:27:33Z | `s50a-control-minimal`             | control                                                                                               | `5779d3799efc42fe` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-numbering-main-calibration`   | calibration (s45's refused shape): two numbering relationships in word/_rels/document.xml.rels        | `4bc3981c4bf63229` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-numbering-relationship`    | invalid: `word-duplicate-numbering-relationship`                              |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-numbering-package-rels`       | #717: the main document's numbering relationship, and two more numbering relationships in _rels/.rels | `7a91d0641a3447e6` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-numbering-relationship`    | invalid: `word-duplicate-numbering-relationship`                              |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-numbering-header-sidecar`     | #717: a referenced header's sidecar holds two numbering relationships                                 | `8a4caad7cdbae5b5` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-numbering-relationship`    | invalid: `paraid-missing-element`, `word-duplicate-numbering-relationship`    |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-numbering-glossary-sidecar`   | #717: a reached glossary's sidecar holds two numbering relationships to two parts                     | `d89bd151c5cba2e3` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-numbering-relationship`    | invalid: `paraid-missing-element`, `word-duplicate-numbering-relationship`    |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-settings-package-rels`        | #717: the main document's settings relationship, and two more settings relationships in _rels/.rels   | `7f0606f9ec18883d` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-settings-relationship`     | invalid: `word-duplicate-settings-relationship`                               |
| `s50a` | 11:26:39Z, 11:27:33Z | `dup-settings-header-sidecar`      | #717: a referenced header's sidecar holds two settings relationships                                  | `9f0933837e0009f6` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-settings-relationship`     | invalid: `paraid-missing-element`, `word-duplicate-settings-relationship`     |
| `s50a` | 11:26:39Z, 11:27:33Z | `s50a-control-minimal-end`         | control                                                                                               | `a2c2d66bb26fa8db` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50b` | 11:28:12Z, 11:28:55Z | `s50b-control-minimal`             | control                                                                                               | `a2c2d66bb26fa8db` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-settings-glossary-sidecar`    | #717: a reached glossary's sidecar holds two settings relationships to two parts                      | `145783ba2b139007` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-settings-relationship`     | invalid: `paraid-missing-element`, `word-duplicate-settings-relationship`     |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-fonttable-header-sidecar`     | #717: a referenced header's sidecar holds two fontTable relationships                                 | `f52469516806b93c` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-font-table-relationship`   | invalid: `paraid-missing-element`, `word-duplicate-font-table-relationship`   |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-fonttable-glossary-sidecar`   | #717: a reached glossary's sidecar holds two fontTable relationships to two parts                     | `1b48db4de4716a31` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-font-table-relationship`   | invalid: `paraid-missing-element`, `word-duplicate-font-table-relationship`   |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-websettings-header-sidecar`   | #717: a referenced header's sidecar holds two webSettings relationships                               | `f7c36a2161e80d84` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-web-settings-relationship` | invalid: `paraid-missing-element`, `word-duplicate-web-settings-relationship` |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-theme-package-rels`           | #717: the main document's theme relationship, and two more theme relationships in _rels/.rels         | `9fdd1040953b5006` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-theme-relationship`        | invalid: `word-duplicate-theme-relationship`                                  |
| `s50b` | 11:28:12Z, 11:28:55Z | `dup-theme-header-sidecar`         | #717: a referenced header's sidecar holds two theme relationships                                     | `9ff901e258c6b513` | clean-open     | clean-open     | clean-open                 | invalid: `word-duplicate-theme-relationship`        | invalid: `paraid-missing-element`, `word-duplicate-theme-relationship`        |
| `s50b` | 11:28:12Z, 11:28:55Z | `s50b-control-minimal-end`         | control                                                                                               | `d53f8c5e25d5343f` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50c` | 11:32:21Z, 11:35:33Z | `s50c-control-minimal`             | control                                                                                               | `e88faecd387ddb0f` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50c` | 11:32:21Z, 11:35:33Z | `main-override-octet-upper`        | #721: main document Override typed APPLICATION/OCTET-STREAM                                           | `f8566bd0501fa667` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50c` | 11:32:21Z, 11:35:33Z | `main-override-octet-charset`      | #721: main document Override typed application/octet-stream; charset=utf-8                            | `abbd077220ed9ace` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50c` | 11:32:21Z, 11:35:33Z | `main-override-image-png`          | #721: main document Override typed image/png                                                          | `913abbf3d76358a7` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50c` | 11:32:21Z, 11:35:33Z | `main-override-foo-xml`            | #721: main document Override typed application/foo+xml                                                | `32f2a7089d4c140f` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50c` | 11:32:21Z, 11:35:33Z | `settings-override-empty`          | #720: a related word/settings.xml whose Override has ContentType=""                                   | `e7c09efffd42aa52` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `xsd-summary`, `xsd-error`                                           |
| `s50c` | 11:32:21Z, 11:35:33Z | `fonttable-override-empty`         | #720: a related word/fontTable.xml whose Override has ContentType=""                                  | `37e686b8e811c72c` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `xsd-summary`, `xsd-error`                                           |
| `s50c` | 11:32:21Z, 11:35:33Z | `s50c-control-minimal-end`         | control                                                                                               | `5812c213248af928` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50d` | 11:39:05Z, 11:40:34Z | `s50d-control-minimal`             | control                                                                                               | `5812c213248af928` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |
| `s50d` | 11:39:05Z, 11:40:34Z | `settings-override-octet`          | #722/F1: a related word/settings.xml typed application/octet-stream                                   | `0e293e78b8137d46` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50d` | 11:39:05Z, 11:40:34Z | `fonttable-override-octet`         | #722/F1: a related word/fontTable.xml typed application/octet-stream                                  | `268025d1d5300770` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50d` | 11:39:05Z, 11:40:34Z | `numbering-override-octet`         | #722/F1: a related word/numbering.xml typed application/octet-stream                                  | `74cf728a50d73b52` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-unrecognized`                                |
| `s50d` | 11:39:05Z, 11:40:34Z | `settings-override-styles-type`    | #722: a related word/settings.xml typed with the styles content type                                  | `3f61cb7f51bcf81b` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-mismatch`                                    |
| `s50d` | 11:39:05Z, 11:40:34Z | `numbering-override-settings-type` | #722: a related word/numbering.xml typed with the settings content type                               | `31f0d21de0126f86` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-mismatch`                                    |
| `s50d` | 11:39:05Z, 11:40:34Z | `main-override-styles-type`        | #722: main document Override typed with the styles content type                                       | `b8564a079df49d24` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `word-part-content-type-mismatch`                                    |
| `s50d` | 11:39:05Z, 11:40:34Z | `s50d-control-minimal-end`         | control                                                                                               | `7edaeba24f7d31e6` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                         |

<details><summary>Raw records, session 50</summary>

```jsonl
{"run": "s50a", "pass": 1, "name": "s50a-control-minimal", "sha256": "5779d3799efc42fed050cf596f79a79f8a48ce12d9bb6299287e2f9a382ab0e1", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00007__wfv__s50a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "s50a-control-minimal", "sha256": "5779d3799efc42fed050cf596f79a79f8a48ce12d9bb6299287e2f9a382ab0e1", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00007__wfv__s50a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 1, "name": "dup-numbering-main-calibration", "sha256": "4bc3981c4bf632290dc3d5e09abb21d38c257607f2c5c39c87dc7eef2259d46f", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00002__wfv__dup-numbering-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:26:21.126 \"Word found unreadable content in 00002__wfv__dup-numbering-main-calibration.docx. Do you want to re … ? If you trust the source of this document, click Yes.\""]}
{"run": "s50a", "pass": 2, "name": "dup-numbering-main-calibration", "sha256": "4bc3981c4bf632290dc3d5e09abb21d38c257607f2c5c39c87dc7eef2259d46f", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00002__wfv__dup-numbering-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:27:30.761 \"Word found unreadable content in 00002__wfv__dup-numbering-main-calibration.docx. Do you want to re … ? If you trust the source of this document, click Yes.\""]}
{"run": "s50a", "pass": 1, "name": "dup-numbering-package-rels", "sha256": "7a91d0641a3447e6a0aba90d9d2765232f9117cd9ddb27bf9e58bf9ca8bf739e", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00003__wfv__dup-numbering-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-numbering-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "dup-numbering-package-rels", "sha256": "7a91d0641a3447e6a0aba90d9d2765232f9117cd9ddb27bf9e58bf9ca8bf739e", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00003__wfv__dup-numbering-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-numbering-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 1, "name": "dup-numbering-header-sidecar", "sha256": "8a4caad7cdbae5b51d30b52502d6a4e6359feec0e1b306634dd98f04fcb2e2fb", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00001__wfv__dup-numbering-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-numbering-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "dup-numbering-header-sidecar", "sha256": "8a4caad7cdbae5b51d30b52502d6a4e6359feec0e1b306634dd98f04fcb2e2fb", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00001__wfv__dup-numbering-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-numbering-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 1, "name": "dup-numbering-glossary-sidecar", "sha256": "d89bd151c5cba2e31806bd7dcafaba9ff124a6ea63bafed309336f7b8d3f644a", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00000__wfv__dup-numbering-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:26:01.053 'Word found unreadable content in 00000__wfv__dup-numbering-glossary-sidecar.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:26:01.781 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-numbering-glossary-si...)\""]}
{"run": "s50a", "pass": 2, "name": "dup-numbering-glossary-sidecar", "sha256": "d89bd151c5cba2e31806bd7dcafaba9ff124a6ea63bafed309336f7b8d3f644a", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00000__wfv__dup-numbering-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:27:02.975 'Word found unreadable content in 00000__wfv__dup-numbering-glossary-sidecar.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:27:03.779 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-numbering-glossary-si...)\""]}
{"run": "s50a", "pass": 1, "name": "dup-settings-package-rels", "sha256": "7f0606f9ec18883d4db23dfe030bfe6f0f8d801628dcbdffd1b25f9e9eeaf642", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00005__wfv__dup-settings-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-settings-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "dup-settings-package-rels", "sha256": "7f0606f9ec18883d4db23dfe030bfe6f0f8d801628dcbdffd1b25f9e9eeaf642", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00005__wfv__dup-settings-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-settings-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 1, "name": "dup-settings-header-sidecar", "sha256": "9f0933837e0009f603cd5ee1e8e1a836ba31188f2669a7dcbca562d021a46cdc", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00004__wfv__dup-settings-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-settings-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "dup-settings-header-sidecar", "sha256": "9f0933837e0009f603cd5ee1e8e1a836ba31188f2669a7dcbca562d021a46cdc", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00004__wfv__dup-settings-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-settings-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 1, "name": "s50a-control-minimal-end", "sha256": "a2c2d66bb26fa8db18750294de1e88544b5ed35a4db0675e9385bf8409131a33", "observedAt": "2026-10-26T11:26:39+00:00", "staged": "00006__wfv__s50a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50a", "pass": 2, "name": "s50a-control-minimal-end", "sha256": "a2c2d66bb26fa8db18750294de1e88544b5ed35a4db0675e9385bf8409131a33", "observedAt": "2026-10-26T11:27:33+00:00", "staged": "00006__wfv__s50a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "s50b-control-minimal", "sha256": "a2c2d66bb26fa8db18750294de1e88544b5ed35a4db0675e9385bf8409131a33", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00007__wfv__s50b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "s50b-control-minimal", "sha256": "a2c2d66bb26fa8db18750294de1e88544b5ed35a4db0675e9385bf8409131a33", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00007__wfv__s50b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "dup-settings-glossary-sidecar", "sha256": "145783ba2b139007ce245c9b83e30906d2599049c0e22b761764ae29d5bc413f", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00002__wfv__dup-settings-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:28:10.823 \"Word found unreadable content in 00002__wfv__dup-settings-glossary-sidecar.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s50b", "pass": 2, "name": "dup-settings-glossary-sidecar", "sha256": "145783ba2b139007ce245c9b83e30906d2599049c0e22b761764ae29d5bc413f", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00002__wfv__dup-settings-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:28:53.472 \"Word found unreadable content in 00002__wfv__dup-settings-glossary-sidecar.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s50b", "pass": 1, "name": "dup-fonttable-header-sidecar", "sha256": "f52469516806b93ccbe1d95421e8df980e878352c62833ede8e8d4415ff17915", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00001__wfv__dup-fonttable-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-fonttable-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "dup-fonttable-header-sidecar", "sha256": "f52469516806b93ccbe1d95421e8df980e878352c62833ede8e8d4415ff17915", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00001__wfv__dup-fonttable-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-fonttable-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "dup-fonttable-glossary-sidecar", "sha256": "1b48db4de4716a3107666883380fabd2587634648f4b249add4deaa3bcba8f40", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00000__wfv__dup-fonttable-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:27:51.929 'Word found unreadable content in 00000__wfv__dup-fonttable-glossary-sidecar.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:27:52.523 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-fonttable-glossary-si...)\""]}
{"run": "s50b", "pass": 2, "name": "dup-fonttable-glossary-sidecar", "sha256": "1b48db4de4716a3107666883380fabd2587634648f4b249add4deaa3bcba8f40", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00000__wfv__dup-fonttable-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:28:34.558 'Word found unreadable content in 00000__wfv__dup-fonttable-glossary-sidecar.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:28:35.153 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__dup-fonttable-glossary-si...)\""]}
{"run": "s50b", "pass": 1, "name": "dup-websettings-header-sidecar", "sha256": "f7c36a2161e80d8465bdb0ff24301bd9b4545404707762e45edfbd84590fc002", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00005__wfv__dup-websettings-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-websettings-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "dup-websettings-header-sidecar", "sha256": "f7c36a2161e80d8465bdb0ff24301bd9b4545404707762e45edfbd84590fc002", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00005__wfv__dup-websettings-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-websettings-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "dup-theme-package-rels", "sha256": "9fdd1040953b50068f510f93776d5981df0d4c600920cf2cec6d4a0a6ff16deb", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00004__wfv__dup-theme-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-theme-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "dup-theme-package-rels", "sha256": "9fdd1040953b50068f510f93776d5981df0d4c600920cf2cec6d4a0a6ff16deb", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00004__wfv__dup-theme-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-theme-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "dup-theme-header-sidecar", "sha256": "9ff901e258c6b5130671cee815c6e54fe35472a43d71a65707da6e47f59537ce", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00003__wfv__dup-theme-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-theme-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "dup-theme-header-sidecar", "sha256": "9ff901e258c6b5130671cee815c6e54fe35472a43d71a65707da6e47f59537ce", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00003__wfv__dup-theme-header-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-theme-header-sidecar_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 1, "name": "s50b-control-minimal-end", "sha256": "d53f8c5e25d5343f400846b23def56cdeeac3cc8623124385c4f5ddfbf55a8ab", "observedAt": "2026-10-26T11:28:12+00:00", "staged": "00006__wfv__s50b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50b", "pass": 2, "name": "s50b-control-minimal-end", "sha256": "d53f8c5e25d5343f400846b23def56cdeeac3cc8623124385c4f5ddfbf55a8ab", "observedAt": "2026-10-26T11:28:55+00:00", "staged": "00006__wfv__s50b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50c", "pass": 1, "name": "s50c-control-minimal", "sha256": "e88faecd387ddb0f1b7a8437855e7065e6e35de06e7b54d08db3984e364114a6", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00006__wfv__s50c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50c", "pass": 2, "name": "s50c-control-minimal", "sha256": "e88faecd387ddb0f1b7a8437855e7065e6e35de06e7b54d08db3984e364114a6", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00006__wfv__s50c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50c", "pass": 1, "name": "main-override-octet-upper", "sha256": "f8566bd0501fa6673bbd87f15d93e82737fd5df32e1da1b807e5bc8cc4791fef", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00004__wfv__main-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:32:15.367 'Word found unreadable content in 00004__wfv__main-override-octet-upper.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'"]}
{"run": "s50c", "pass": 2, "name": "main-override-octet-upper", "sha256": "f8566bd0501fa6673bbd87f15d93e82737fd5df32e1da1b807e5bc8cc4791fef", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00004__wfv__main-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:35:27.473 'Word found unreadable content in 00004__wfv__main-override-octet-upper.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'"]}
{"run": "s50c", "pass": 1, "name": "main-override-octet-charset", "sha256": "abbd077220ed9acef340ebff46329176a272f11da6cd47c148c77ef0751fb1a1", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00003__wfv__main-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:31:39.870 Microsoft Word, Word found unreadable content in 00003__wfv__main-override-octet-charset.docx. Do yo … t? If you trust the source of this document, click Yes."]}
{"run": "s50c", "pass": 2, "name": "main-override-octet-charset", "sha256": "abbd077220ed9acef340ebff46329176a272f11da6cd47c148c77ef0751fb1a1", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00003__wfv__main-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:34:52.151 'Word found unreadable content in 00003__wfv__main-override-octet-charset.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s50c", "pass": 1, "name": "main-override-image-png", "sha256": "913abbf3d76358a738357d4a6d7f791d10bc828f4a074e1b8aff9b8d8277be8f", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00002__wfv__main-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:30:54.940 Microsoft Word, Word found unreadable content in 00002__wfv__main-override-image-png.docx. Do you wa … t? If you trust the source of this document, click Yes.", "2026-10-26 07:30:55.639 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-override-image-png.docx)\""]}
{"run": "s50c", "pass": 2, "name": "main-override-image-png", "sha256": "913abbf3d76358a738357d4a6d7f791d10bc828f4a074e1b8aff9b8d8277be8f", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00002__wfv__main-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:34:16.730 Microsoft Word, Word found unreadable content in 00002__wfv__main-override-image-png.docx. Do you wa … t? If you trust the source of this document, click Yes."]}
{"run": "s50c", "pass": 1, "name": "main-override-foo-xml", "sha256": "32f2a7089d4c140fd6d8bb3d6239998bbcef48a19e11ee60ccc187f47fd97c52", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00001__wfv__main-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:30:06.331 Microsoft Word, Word found unreadable content in 00001__wfv__main-override-foo-xml.docx. Do you want … t? If you trust the source of this document, click Yes."]}
{"run": "s50c", "pass": 2, "name": "main-override-foo-xml", "sha256": "32f2a7089d4c140fd6d8bb3d6239998bbcef48a19e11ee60ccc187f47fd97c52", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00001__wfv__main-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:33:32.613 Microsoft Word, Word found unreadable content in 00001__wfv__main-override-foo-xml.docx. Do you want … t? If you trust the source of this document, click Yes.", "2026-10-26 07:33:33.308 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00001__wfv__main-override-foo-xml.docx)\""]}
{"run": "s50c", "pass": 1, "name": "settings-override-empty", "sha256": "e7c09efffd42aa522ac47ceb2103d5ec6d9a8eee9393d930b662b4e84bb57749", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00007__wfv__settings-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:32:21.796 \"Word found unreadable content in 00007__wfv__settings-override-empty.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\"", "2026-10-26 07:32:21.796 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-empty.docx)\""]}
{"run": "s50c", "pass": 2, "name": "settings-override-empty", "sha256": "e7c09efffd42aa522ac47ceb2103d5ec6d9a8eee9393d930b662b4e84bb57749", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00007__wfv__settings-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:35:33.596 \"Word found unreadable content in 00007__wfv__settings-override-empty.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\"", "2026-10-26 07:35:33.597 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-empty.docx)\""]}
{"run": "s50c", "pass": 1, "name": "fonttable-override-empty", "sha256": "37e686b8e811c72ce3a6f9a58a5c7f53eb667c41106709ed185c608f6d87f01d", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00000__wfv__fonttable-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:29:13.610 'Word found unreadable content in 00000__wfv__fonttable-override-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:29:14.217 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-empty....)\""]}
{"run": "s50c", "pass": 2, "name": "fonttable-override-empty", "sha256": "37e686b8e811c72ce3a6f9a58a5c7f53eb667c41106709ed185c608f6d87f01d", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00000__wfv__fonttable-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:32:39.826 'Word found unreadable content in 00000__wfv__fonttable-override-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:32:40.391 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-empty....)\""]}
{"run": "s50c", "pass": 1, "name": "s50c-control-minimal-end", "sha256": "5812c213248af928fc53ed11bb7a9169dbc44a4c01b068be2b0ab4748125c7d0", "observedAt": "2026-10-26T11:32:21+00:00", "staged": "00005__wfv__s50c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50c", "pass": 2, "name": "s50c-control-minimal-end", "sha256": "5812c213248af928fc53ed11bb7a9169dbc44a4c01b068be2b0ab4748125c7d0", "observedAt": "2026-10-26T11:35:33+00:00", "staged": "00005__wfv__s50c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50d", "pass": 1, "name": "s50d-control-minimal", "sha256": "5812c213248af928fc53ed11bb7a9169dbc44a4c01b068be2b0ab4748125c7d0", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00005__wfv__s50d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50d", "pass": 2, "name": "s50d-control-minimal", "sha256": "5812c213248af928fc53ed11bb7a9169dbc44a4c01b068be2b0ab4748125c7d0", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00005__wfv__s50d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50d", "pass": 1, "name": "settings-override-octet", "sha256": "0e293e78b8137d46996955ebbe4c745c9c68d264a37f3a8ef2bb49c20e312971", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00006__wfv__settings-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:37:57.270 \"Word found unreadable content in 00006__wfv__settings-override-octet.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\"", "2026-10-26 07:37:57.271 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-octet.docx)\""]}
{"run": "s50d", "pass": 2, "name": "settings-override-octet", "sha256": "0e293e78b8137d46996955ebbe4c745c9c68d264a37f3a8ef2bb49c20e312971", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00006__wfv__settings-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:40:29.578 'Word found unreadable content in 00006__wfv__settings-override-octet.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:40:30.304 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-octet.docx)\""]}
{"run": "s50d", "pass": 1, "name": "fonttable-override-octet", "sha256": "268025d1d53007702495eaebcce17d72e7fb057e18a38bcc237b05b627cae33e", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00000__wfv__fonttable-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:35:52.704 'Word found unreadable content in 00000__wfv__fonttable-override-octet.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:35:53.309 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-octet....)\""]}
{"run": "s50d", "pass": 2, "name": "fonttable-override-octet", "sha256": "268025d1d53007702495eaebcce17d72e7fb057e18a38bcc237b05b627cae33e", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00000__wfv__fonttable-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:39:23.027 'Word found unreadable content in 00000__wfv__fonttable-override-octet.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:39:23.770 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-octet....)\""]}
{"run": "s50d", "pass": 1, "name": "numbering-override-octet", "sha256": "74cf728a50d73b52049b3ccf24e1a599413bd39c70f7e1d78009b73f08ae65d2", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00002__wfv__numbering-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:37:19.111 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00002__wfv__numbering-override-octet....)'", "2026-10-26 07:37:19.261 \"Word found unreadable content in 00002__wfv__numbering-override-octet.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s50d", "pass": 2, "name": "numbering-override-octet", "sha256": "74cf728a50d73b52049b3ccf24e1a599413bd39c70f7e1d78009b73f08ae65d2", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00002__wfv__numbering-override-octet.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:40:20.731 'Word found unreadable content in 00002__wfv__numbering-override-octet.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:40:21.570 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__numbering-override-octet....)\""]}
{"run": "s50d", "pass": 1, "name": "settings-override-styles-type", "sha256": "3f61cb7f51bcf81bfd6c1256dc5ab1f7c5c384877d4dfcaaafebc3a8190135f0", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00007__wfv__settings-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:38:51.265 Microsoft Word, Word found unreadable content in 00007__wfv__settings-override-styles-type.docx. Do  … t? If you trust the source of this document, click Yes.", "2026-10-26 07:39:05.468 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-styles-...)\""]}
{"run": "s50d", "pass": 2, "name": "settings-override-styles-type", "sha256": "3f61cb7f51bcf81bfd6c1256dc5ab1f7c5c384877d4dfcaaafebc3a8190135f0", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00007__wfv__settings-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:40:34.299 'Word found unreadable content in 00007__wfv__settings-override-styles-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:40:34.888 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-styles-...)\""]}
{"run": "s50d", "pass": 1, "name": "numbering-override-settings-type", "sha256": "31f0d21de0126f8630116a947965a72789e44d8e443c6a7c1689b5ad57f6d78a", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00003__wfv__numbering-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:37:50.083 'Word found unreadable content in 00003__wfv__numbering-override-settings-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s50d", "pass": 2, "name": "numbering-override-settings-type", "sha256": "31f0d21de0126f8630116a947965a72789e44d8e443c6a7c1689b5ad57f6d78a", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00003__wfv__numbering-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:40:24.977 'Word found unreadable content in 00003__wfv__numbering-override-settings-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:40:25.563 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-override-settin...)\""]}
{"run": "s50d", "pass": 1, "name": "main-override-styles-type", "sha256": "b8564a079df49d2465726d1719581a4417d29ba8ab81a2afec7170400d53b23d", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00001__wfv__main-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:36:41.630 'Word found unreadable content in 00001__wfv__main-override-styles-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'"]}
{"run": "s50d", "pass": 2, "name": "main-override-styles-type", "sha256": "b8564a079df49d2465726d1719581a4417d29ba8ab81a2afec7170400d53b23d", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00001__wfv__main-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:40:16.455 Microsoft Word, Word found unreadable content in 00001__wfv__main-override-styles-type.docx. Do you  … t? If you trust the source of this document, click Yes."]}
{"run": "s50d", "pass": 1, "name": "s50d-control-minimal-end", "sha256": "7edaeba24f7d31e6b1f1c0e4a133c6460619e04ad20c339a60f61f53a9cf8c34", "observedAt": "2026-10-26T11:39:05+00:00", "staged": "00004__wfv__s50d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s50d", "pass": 2, "name": "s50d-control-minimal-end", "sha256": "7edaeba24f7d31e6b1f1c0e4a133c6460619e04ad20c339a60f61f53a9cf8c34", "observedAt": "2026-10-26T11:40:34+00:00", "staged": "00004__wfv__s50d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s50d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 50 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s50builder.mts`:

```ts
// Session 50 (2026-10-26): the scope the session 49 follow-ups (#717, #720, #721, #722) need before they are implemented.
// - s50a/s50b: #717. Session 49 opened clean two extra styles relationships in `_rels/.rels` and in a referenced
//   header's sidecar, and refused them in a reached glossary's sidecar. Here the same three reaches with two numbering,
//   settings, fontTable, webSettings or theme relationships; session 45 refused two of each only in
//   `word/_rels/document.xml.rels` (numbering re-run here as the calibration).
// - s50c: #721 and #720. Session 49 refused the main document's Override typed `application/octet-stream` and the
//   styles Override with `ContentType=""`. Here the main document typed with the other s49a spellings (upper case, a
//   parameter, `image/png`, `application/foo+xml`), and an empty ContentType on a related settings and fontTable part.
// - s50d: #722 and review finding 1's reach. Session 49 refused styles typed `application/octet-stream` and typed with
//   the settings type. Here settings, fontTable and numbering typed `application/octet-stream`, settings typed with
//   the styles type, numbering with the settings type, and the main document with the styles type.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s50a pnpm exec tsx s50builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN_TYPE = `${WML}.document.main+xml`;
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

/** A Word-clean fixture's theme part (Word 16.115 clean-open in the manifest). */
const THEME_XML = await (async () => {
    const zip = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.drawing-arc-radius-integer.docx"));
    const file = zip.file("word/theme/theme1.xml");
    if (!file) throw new Error("theme fixture lost word/theme/theme1.xml");
    return file.async("string");
})();

type Kind = "numbering" | "settings" | "fontTable" | "webSettings" | "theme";
/** The relationship segment, the part body and the content type of each kind (the bodies session 47 used). */
const KINDS: Record<Kind, { root: string; ct: string }> = {
    numbering: { root: `${XML_DECL}<w:numbering xmlns:w="${W}"/>`, ct: `${WML}.numbering+xml` },
    settings: { root: `${XML_DECL}<w:settings xmlns:w="${W}"/>`, ct: `${WML}.settings+xml` },
    fontTable: { root: `${XML_DECL}<w:fonts xmlns:w="${W}"/>`, ct: `${WML}.fontTable+xml` },
    webSettings: { root: `${XML_DECL}<w:webSettings xmlns:w="${W}"/>`, ct: `${WML}.webSettings+xml` },
    theme: { root: THEME_XML, ct: "application/vnd.openxmlformats-officedocument.theme+xml" },
};
/** Where a kind's parts live: `theme/theme1.xml` for the theme, `<kind>.xml` otherwise. */
const fileOf = (kind: Kind, n: 1 | 2) => (kind === "theme" ? `theme/theme${n}.xml` : `${kind}${n === 1 ? "" : "2"}.xml`);

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${REL}/${segment}" Target="${target}"/>`;
const relsPart = (body: string) =>
    `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/** The minimal package plus `word/<file of kind>` related from the main document's sidecar as rId2. */
const withRelated = (kind: Kind, type = KINDS[kind].ct): Record<string, string> => ({
    ...P,
    [`word/${fileOf(kind, 1)}`]: KINDS[kind].root,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", kind, fileOf(kind, 1))),
    [CT]: overrides(P[CT]!, [`word/${fileOf(kind, 1)}`, type]),
});
/** {@link withRelated} with the Override of the related part (or of `part`) carrying `type`. */
const relatedTyped = (kind: Kind, type: string) => buildDocx(withRelated(kind, type));
const retyped = (part: string, own: string, type: string) =>
    buildDocx({
        ...P,
        [CT]: replaceOnce(
            P[CT]!,
            `<Override PartName="/${part}" ContentType="${own}"/>`,
            `<Override PartName="/${part}" ContentType="${type}"/>`,
        ),
    });
const mainTyped = (type: string) => retyped("word/document.xml", MAIN_TYPE, type);

/** Session 45's refused shape: two relationships of `kind` to two parts in the main document's sidecar. */
const dupInMainRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rId3", kind, fileOf(kind, 2))),
        [CT]: overrides(parts[CT]!, [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
/** The main document's own `kind` relationship, and two more of `kind` in `_rels/.rels` (s49c's styles shape). */
const dupInPackageRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "_rels/.rels": appendRels(
            P["_rels/.rels"]!,
            `${relationship("rId8", kind, `word/${fileOf(kind, 1)}`)}${relationship("rId9", kind, `word/${fileOf(kind, 2)}`)}`,
        ),
        [CT]: overrides(parts[CT]!, [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
const HEADER = `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
/** The main document's own `kind` relationship, and a referenced header whose sidecar holds two of `kind`. */
const dupInHeaderRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "word/document.xml": replaceOnce(
            replaceOnce(P["word/document.xml"]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:sectPr>",
            `<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>`,
        ),
        "word/header9.xml": HEADER,
        "word/_rels/header9.xml.rels": relsPart(
            `${relationship("rId1", kind, fileOf(kind, 1))}${relationship("rId2", kind, fileOf(kind, 2))}`,
        ),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header9.xml")),
        [CT]: overrides(parts[CT]!, ["word/header9.xml", `${WML}.header+xml`], [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
const GLOSSARY =
    `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/** A reached glossary whose own sidecar holds two relationships of `kind` to two parts in its folder (s49c's shape). */
const dupInGlossaryRels = (kind: Kind) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        [`word/glossary/${fileOf(kind, 1)}`]: KINDS[kind].root,
        [`word/glossary/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "word/glossary/_rels/document.xml.rels": relsPart(
            `${relationship("rId1", kind, fileOf(kind, 1))}${relationship("rId2", kind, fileOf(kind, 2))}`,
        ),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
        [CT]: overrides(
            P[CT]!,
            ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
            [`word/glossary/${fileOf(kind, 1)}`, KINDS[kind].ct],
            [`word/glossary/${fileOf(kind, 2)}`, KINDS[kind].ct],
        ),
    });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s50a: [
        ["s50a-control-minimal", "control", control],
        [
            "dup-numbering-main-calibration",
            "calibration (s45's refused shape): two numbering relationships in word/_rels/document.xml.rels",
            () => dupInMainRels("numbering"),
        ],
        [
            "dup-numbering-package-rels",
            "#717: the main document's numbering relationship, and two more numbering relationships in _rels/.rels",
            () => dupInPackageRels("numbering"),
        ],
        [
            "dup-numbering-header-sidecar",
            "#717: a referenced header's sidecar holds two numbering relationships",
            () => dupInHeaderRels("numbering"),
        ],
        [
            "dup-numbering-glossary-sidecar",
            "#717: a reached glossary's sidecar holds two numbering relationships to two parts",
            () => dupInGlossaryRels("numbering"),
        ],
        [
            "dup-settings-package-rels",
            "#717: the main document's settings relationship, and two more settings relationships in _rels/.rels",
            () => dupInPackageRels("settings"),
        ],
        [
            "dup-settings-header-sidecar",
            "#717: a referenced header's sidecar holds two settings relationships",
            () => dupInHeaderRels("settings"),
        ],
        ["s50a-control-minimal-end", "control", control],
    ],
    s50b: [
        ["s50b-control-minimal", "control", control],
        [
            "dup-settings-glossary-sidecar",
            "#717: a reached glossary's sidecar holds two settings relationships to two parts",
            () => dupInGlossaryRels("settings"),
        ],
        [
            "dup-fonttable-header-sidecar",
            "#717: a referenced header's sidecar holds two fontTable relationships",
            () => dupInHeaderRels("fontTable"),
        ],
        [
            "dup-fonttable-glossary-sidecar",
            "#717: a reached glossary's sidecar holds two fontTable relationships to two parts",
            () => dupInGlossaryRels("fontTable"),
        ],
        [
            "dup-websettings-header-sidecar",
            "#717: a referenced header's sidecar holds two webSettings relationships",
            () => dupInHeaderRels("webSettings"),
        ],
        [
            "dup-theme-package-rels",
            "#717: the main document's theme relationship, and two more theme relationships in _rels/.rels",
            () => dupInPackageRels("theme"),
        ],
        ["dup-theme-header-sidecar", "#717: a referenced header's sidecar holds two theme relationships", () => dupInHeaderRels("theme")],
        ["s50b-control-minimal-end", "control", control],
    ],
    s50c: [
        ["s50c-control-minimal", "control", control],
        [
            "main-override-octet-upper",
            "#721: main document Override typed APPLICATION/OCTET-STREAM",
            () => mainTyped("APPLICATION/OCTET-STREAM"),
        ],
        [
            "main-override-octet-charset",
            "#721: main document Override typed application/octet-stream; charset=utf-8",
            () => mainTyped("application/octet-stream; charset=utf-8"),
        ],
        ["main-override-image-png", "#721: main document Override typed image/png", () => mainTyped("image/png")],
        ["main-override-foo-xml", "#721: main document Override typed application/foo+xml", () => mainTyped("application/foo+xml")],
        [
            "settings-override-empty",
            '#720: a related word/settings.xml whose Override has ContentType=""',
            () => relatedTyped("settings", ""),
        ],
        [
            "fonttable-override-empty",
            '#720: a related word/fontTable.xml whose Override has ContentType=""',
            () => relatedTyped("fontTable", ""),
        ],
        ["s50c-control-minimal-end", "control", control],
    ],
    s50d: [
        ["s50d-control-minimal", "control", control],
        [
            "settings-override-octet",
            "#722/F1: a related word/settings.xml typed application/octet-stream",
            () => relatedTyped("settings", "application/octet-stream"),
        ],
        [
            "fonttable-override-octet",
            "#722/F1: a related word/fontTable.xml typed application/octet-stream",
            () => relatedTyped("fontTable", "application/octet-stream"),
        ],
        [
            "numbering-override-octet",
            "#722/F1: a related word/numbering.xml typed application/octet-stream",
            () => relatedTyped("numbering", "application/octet-stream"),
        ],
        [
            "settings-override-styles-type",
            "#722: a related word/settings.xml typed with the styles content type",
            () => relatedTyped("settings", STYLES_TYPE),
        ],
        [
            "numbering-override-settings-type",
            "#722: a related word/numbering.xml typed with the settings content type",
            () => relatedTyped("numbering", KINDS.settings.ct),
        ],
        ["main-override-styles-type", "#722: main document Override typed with the styles content type", () => mainTyped(STYLES_TYPE)],
        ["s50d-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-50 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s50a", "s50b", "s50c", "s50d")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s50/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-50 parts of docs/plans/evidence/word-probes-2026-10-24.md into s50/section.md.

Reads the chunk's specimens.jsonl (validator columns at 01e4e684, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s50/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s50a", "s50b", "s50c", "s50d")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s50/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 50: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 01e4e684",
    "",
    "The scope the session 49 follow-ups need: where Word refuses duplicate relationships "
    "([#717](https://github.com/jandira-tech/docx-validate/issues/717)), and which content types it refuses on the main document "
    "and the other parts it relates ([#720](https://github.com/jandira-tech/docx-validate/issues/720), "
    "[#721](https://github.com/jandira-tech/docx-validate/issues/721), [#722](https://github.com/jandira-tech/docx-validate/issues/722)). "
    "Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own "
    "Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both "
    "readings agree, and `unknown` otherwise; all 32 rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen. The part bodies are session 47's empty roots; the theme part is "
    "`word/theme/theme1.xml` of `tests/fixtures/working/package.drawing-arc-radius-integer.docx` (clean-open in the manifest).",
    "",
    "- `s50a` and `s50b`, #717: two relationships of one kind outside the main document's relationships part. In `_rels/.rels` "
    "(beside the main document's own relationship of the kind) two numbering, settings or theme relationships open clean, as styles "
    "did in session 49; in the sidecar of a header the body references, two numbering, settings, fontTable, webSettings or theme "
    "relationships open clean. In a reached glossary's sidecar, two numbering, settings or fontTable relationships to two parts get "
    "the recovery offer, as styles did; so does session 45's numbering calibration in `word/_rels/document.xml.rels`. Word-valid "
    "rejects every one of them, so the eight clean rows are false positives.",
    "- `s50c`, #721 and #720: the main document's Override typed `APPLICATION/OCTET-STREAM`, `application/octet-stream; charset=utf-8`, "
    "`image/png` or `application/foo+xml`, and an empty `ContentType=\"\"` on the Override of a related settings or fontTable part, "
    "get the recovery offer; word-valid passes all six (false negatives).",
    "- `s50d`, #722 and review finding 1: a related settings, fontTable or numbering part typed `application/octet-stream`, settings "
    "typed with the styles content type, numbering with the settings content type, and the main document with the styles content "
    "type get the recovery offer; word-valid passes all six (false negatives).",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 01e4e684 | strict at 01e4e684 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 50</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 50 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s50builder.mts", ROOT / "s50builder.mts", "ts"), ("compare.py", ROOT / "s50/compare.py", "python"),
                         ("section.py", ROOT / "s50/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s50/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 51: 11:55Z–11:57Z on 2026-10-26, validator columns at e762ffb5

The scope of `word-part-reference-relationship` (layer 147, [#705](https://github.com/jandira-tech/docx-validate/issues/705)), which walks the parts whose name looks like a story instead of the parts Word reads; the shapes are the review of layers 147–150's findings 1–4 ([#726](https://github.com/jandira-tech/docx-validate/issues/726)). The chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 8 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A header the body references, holding a chart whose `c:chart r:id` names an image relationship to a real PNG, gets the recovery offer stored as `word/header1.xml` (the calibration) and as `word/headerFirst.xml`; so does the main document stored as `word/main.xml` with the same reference. Word-valid rejects only `word/header1.xml`: the other two are false negatives.
- The same header related by the main document but named by no `w:headerReference` opens clean, with its relationships part and without one, and so does a glossary document no relationship reaches holding the same reference (as sessions 15 and 35 predicted). Word-valid rejects all three through `word-part-reference-relationship`: false positives.

| Run    | Observed             | Specimen                                     | Shape                                                                                                      | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at e762ffb5                      | strict at e762ffb5                                                                                                 |
| ------ | -------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `s51a` | 11:55:15Z, 11:57:27Z | `s51a-control-minimal`                       | control                                                                                                    | `bb3e60c5a7751c97` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                              |
| `s51a` | 11:55:15Z, 11:57:27Z | `header1-referenced-chart-image-calibration` | calibration: a referenced word/header1.xml whose c:chart r:id names an image relationship                  | `4d37fd37a53b26ec` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship` | invalid: `paraid-missing-element`, `word-part-reference-relationship`                                              |
| `s51a` | 11:55:15Z, 11:57:27Z | `headerfirst-referenced-chart-image`         | review F3: the same header stored as word/headerFirst.xml                                                  | `80688107f2b2dacd` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | valid                                                                                                              |
| `s51a` | 11:55:15Z, 11:57:27Z | `main-renamed-chart-image`                   | review F3: the main document stored as word/main.xml, its c:chart r:id naming an image relationship        | `842c3f1237199000` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | valid                                                                                                              |
| `s51a` | 11:55:15Z, 11:57:27Z | `unused-header-chart-image`                  | review F1: an unused header (related, no w:headerReference) whose c:chart r:id names an image relationship | `e41d8e1979abf5cb` | clean-open     | clean-open     | clean-open                 | invalid: `word-part-reference-relationship` | invalid: `paraid-missing-element`, `word-part-reference-relationship`                                              |
| `s51a` | 11:55:15Z, 11:57:27Z | `unused-header-chart-no-sidecar`             | review F4: the unused header with no relationships part                                                    | `19d5e84d8c649d5b` | clean-open     | clean-open     | clean-open                 | invalid: `word-part-reference-relationship` | invalid: `rels-unreferenced`, `rels-missing-sidecar`, `paraid-missing-element`, `word-part-reference-relationship` |
| `s51a` | 11:55:15Z, 11:57:27Z | `unreached-glossary-chart-image`             | review F2: a glossary no relationship reaches whose c:chart r:id names an image relationship               | `71002656f45f7e0e` | clean-open     | clean-open     | clean-open                 | invalid: `word-part-reference-relationship` | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-part-reference-relationship`                         |
| `s51a` | 11:55:15Z, 11:57:27Z | `s51a-control-minimal-end`                   | control                                                                                                    | `f74fbbfcf7657eb2` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                              |

<details><summary>Raw records, session 51</summary>

```jsonl
{"run": "s51a", "pass": 1, "name": "s51a-control-minimal", "sha256": "bb3e60c5a7751c973b79208a6b79300af8fa501a83f2327cc99cb9f31c831eed", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00004__wfv__s51a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s51a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 2, "name": "s51a-control-minimal", "sha256": "bb3e60c5a7751c973b79208a6b79300af8fa501a83f2327cc99cb9f31c831eed", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00004__wfv__s51a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s51a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 1, "name": "header1-referenced-chart-image-calibration", "sha256": "4d37fd37a53b26eca536cc220dd01e86fd7fbdb22e12c2aa9dae359f94454ca8", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00000__wfv__header1-referenced-chart-image-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:51:59.875 'Word found unreadable content in 00000__wfv__header1-referenced-chart-image-calibration.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:52:00.544 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header1-referenced-chart-...)\""]}
{"run": "s51a", "pass": 2, "name": "header1-referenced-chart-image-calibration", "sha256": "4d37fd37a53b26eca536cc220dd01e86fd7fbdb22e12c2aa9dae359f94454ca8", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00000__wfv__header1-referenced-chart-image-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:55:49.193 'Word found unreadable content in 00000__wfv__header1-referenced-chart-image-calibration.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-26 07:55:49.826 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header1-referenced-chart-...)\""]}
{"run": "s51a", "pass": 1, "name": "headerfirst-referenced-chart-image", "sha256": "80688107f2b2dacdf9a376942c3f2ee075a88b84fcb932f73ee65dc379dd6770", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00001__wfv__headerfirst-referenced-chart-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:52:58.993 Microsoft Word, Word found unreadable content in 00001__wfv__headerfirst-referenced-chart-image.docx … t? If you trust the source of this document, click Yes."]}
{"run": "s51a", "pass": 2, "name": "headerfirst-referenced-chart-image", "sha256": "80688107f2b2dacdf9a376942c3f2ee075a88b84fcb932f73ee65dc379dd6770", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00001__wfv__headerfirst-referenced-chart-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:57:07.595 \"Word found unreadable content in 00001__wfv__headerfirst-referenced-chart-image.docx. Do you want t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s51a", "pass": 1, "name": "main-renamed-chart-image", "sha256": "842c3f1237199000e73c634aebd04aaf207f70374a2f92319c0cf95d929a76d3", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00002__wfv__main-renamed-chart-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:55:07.690 Microsoft Word, Word found unreadable content in 00002__wfv__main-renamed-chart-image.docx. Do you w … t? If you trust the source of this document, click Yes.", "2026-10-26 07:55:12.678 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-renamed-chart-image....)\""]}
{"run": "s51a", "pass": 2, "name": "main-renamed-chart-image", "sha256": "842c3f1237199000e73c634aebd04aaf207f70374a2f92319c0cf95d929a76d3", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00002__wfv__main-renamed-chart-image.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 07:57:25.032 \"Word found unreadable content in 00002__wfv__main-renamed-chart-image.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s51a", "pass": 1, "name": "unused-header-chart-image", "sha256": "e41d8e1979abf5cba631412af3135d20343d8a04266162d0d3e082646385db21", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00006__wfv__unused-header-chart-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header-chart-image_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 2, "name": "unused-header-chart-image", "sha256": "e41d8e1979abf5cba631412af3135d20343d8a04266162d0d3e082646385db21", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00006__wfv__unused-header-chart-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header-chart-image_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 1, "name": "unused-header-chart-no-sidecar", "sha256": "19d5e84d8c649d5b12bf868f4d3f002dab1b4e4aa1c422939290dee51325049a", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00007__wfv__unused-header-chart-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header-chart-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 2, "name": "unused-header-chart-no-sidecar", "sha256": "19d5e84d8c649d5b12bf868f4d3f002dab1b4e4aa1c422939290dee51325049a", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00007__wfv__unused-header-chart-no-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header-chart-no-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 1, "name": "unreached-glossary-chart-image", "sha256": "71002656f45f7e0e785cf7c9fef8cda14f0880b177bc3589917f02cc93f533c6", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00005__wfv__unreached-glossary-chart-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-chart-image_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 2, "name": "unreached-glossary-chart-image", "sha256": "71002656f45f7e0e785cf7c9fef8cda14f0880b177bc3589917f02cc93f533c6", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00005__wfv__unreached-glossary-chart-image.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-chart-image_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 1, "name": "s51a-control-minimal-end", "sha256": "f74fbbfcf7657eb2908ef2c95c2c718a2ab099789e78458039aaed0dbc9478cd", "observedAt": "2026-10-26T11:55:15+00:00", "staged": "00003__wfv__s51a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s51a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s51a", "pass": 2, "name": "s51a-control-minimal-end", "sha256": "f74fbbfcf7657eb2908ef2c95c2c718a2ab099789e78458039aaed0dbc9478cd", "observedAt": "2026-10-26T11:57:27+00:00", "staged": "00003__wfv__s51a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s51a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 51 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s51builder.mts`:

```ts
// Session 51 (2026-10-26): the scope of layer 147's `word-part-reference-relationship` (#705), which walks the parts
// whose NAME looks like a story (`ctx.storyParts()`), not the parts Word reads. The review of layers 147–150 (findings
// 1–4) built these shapes; session 15 (an unreferenced malformed header opens clean) and session 35 (an unreached
// glossary is not read) predict the clean ones, but no session showed Word a chart reference in such a part.
// - an unused header (related, named by no `w:headerReference`) holding a `c:chart r:id` that names an image
//   relationship, with its sidecar and with none;
// - the main document stored as `word/main.xml` holding the same reference;
// - a glossary document no relationship reaches holding the same reference;
// - a header the body references, stored as `word/headerFirst.xml`, holding the same reference, beside the same
//   header stored as `word/header1.xml` (the calibration: session 46 refused the shape in the main document).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s51a pnpm exec tsx s51builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "base64"),
);
const DRAWING_NS = `xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:r="${R}"`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const relsPart = (body: string) =>
    `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
/** The minimal content types plus a `png` Default and the given Overrides. */
const types = (...overrides: Array<[string, string]>) =>
    replaceOnce(
        replaceOnce(P[CT]!, '<Default Extension="rels"', '<Default Extension="png" ContentType="image/png"/><Default Extension="rels"'),
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
/** A paragraph holding a chart drawing whose `c:chart r:id` is `id` (the review's CHART_DRAWING). */
const chartParagraph = (id: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart r:id="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const header = () => `${XML_DECL}<w:hdr xmlns:w="${W}" ${DRAWING_NS}>${chartParagraph("rId1")}</w:hdr>`;
/** A story part's sidecar whose rId1 is an image relationship to the PNG. */
const imageSidecar = () => relsPart(relationship("rId1", "image", "media/image1.png"));
const control = () => buildDocx({ ...P });

/** An unused header: related as rIdH by the main document, named by no `w:headerReference`. */
const unusedHeader = (withSidecar: boolean) =>
    buildDocx({
        ...P,
        "word/media/image1.png": PNG,
        "word/header1.xml": header(),
        ...(withSidecar ? { "word/_rels/header1.xml.rels": imageSidecar() } : {}),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
        [CT]: types(["word/header1.xml", `${WML}.header+xml`]),
    });
/** A header the body references through `w:headerReference r:id="rIdH"`, stored as `word/<file>`. */
const referencedHeader = (file: string) =>
    buildDocx({
        ...P,
        "word/media/image1.png": PNG,
        [`word/${file}`]: header(),
        [`word/_rels/${file}.rels`]: imageSidecar(),
        [MAIN]: replaceOnce(
            replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`),
            "<w:sectPr>",
            `<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>`,
        ),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", file)),
        [CT]: types([`word/${file}`, `${WML}.header+xml`]),
    });
/** The main document stored as `word/main.xml`, its body holding a chart whose `c:chart r:id` names an image relationship. */
const renamedMain = () => {
    const parts: Record<string, string | Uint8Array> = {
        ...P,
        "word/media/image1.png": PNG,
        "word/main.xml": replaceOnce(
            replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" ${DRAWING_NS}`),
            "<w:sectPr>",
            `${chartParagraph("rIdI")}<w:sectPr>`,
        ),
        "word/_rels/main.xml.rels": appendRels(P[SIDECAR]!, relationship("rIdI", "image", "media/image1.png")),
        "_rels/.rels": replaceOnce(P["_rels/.rels"]!, 'Target="word/document.xml"', 'Target="word/main.xml"'),
        [CT]: replaceOnce(types(), '<Override PartName="/word/document.xml"', '<Override PartName="/word/main.xml"'),
    };
    delete parts[MAIN];
    delete parts[SIDECAR];
    return buildDocx(parts);
};
/** A glossary document no relationship reaches, its part body holding the same chart reference. */
const unreachedGlossary = () =>
    buildDocx({
        ...P,
        "word/media/image1.png": PNG,
        "word/glossary/document.xml":
            `${XML_DECL}<w:glossaryDocument xmlns:w="${W}" ${DRAWING_NS}><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
            `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
            `<w:docPartBody>${chartParagraph("rId1")}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
        "word/glossary/_rels/document.xml.rels": relsPart(relationship("rId1", "image", "../media/image1.png")),
        [CT]: types(["word/glossary/document.xml", `${WML}.document.glossary+xml`]),
    });

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s51a: [
        ["s51a-control-minimal", "control", control],
        [
            "header1-referenced-chart-image-calibration",
            "calibration: a referenced word/header1.xml whose c:chart r:id names an image relationship",
            () => referencedHeader("header1.xml"),
        ],
        [
            "headerfirst-referenced-chart-image",
            "review F3: the same header stored as word/headerFirst.xml",
            () => referencedHeader("headerFirst.xml"),
        ],
        [
            "main-renamed-chart-image",
            "review F3: the main document stored as word/main.xml, its c:chart r:id naming an image relationship",
            renamedMain,
        ],
        [
            "unused-header-chart-image",
            "review F1: an unused header (related, no w:headerReference) whose c:chart r:id names an image relationship",
            () => unusedHeader(true),
        ],
        ["unused-header-chart-no-sidecar", "review F4: the unused header with no relationships part", () => unusedHeader(false)],
        [
            "unreached-glossary-chart-image",
            "review F2: a glossary no relationship reaches whose c:chart r:id names an image relationship",
            unreachedGlossary,
        ],
        ["s51a-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-51 chunk: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s51a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s51/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-51 parts of docs/plans/evidence/word-probes-2026-10-24.md into s51/section.md.

Reads the chunk's specimens.jsonl (validator columns at e762ffb5, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s51/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s51a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s51/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 51: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at e762ffb5",
    "",
    "The scope of `word-part-reference-relationship` (layer 147, [#705](https://github.com/jandira-tech/docx-validate/issues/705)), "
    "which walks the parts whose name looks like a story instead of the parts Word reads; the shapes are the review of layers 147–150's "
    "findings 1–4 ([#726](https://github.com/jandira-tech/docx-validate/issues/726)). The chunk ran twice, as two separate driver runs "
    "of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 8 rows "
    "agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A header the body references, holding a chart whose `c:chart r:id` names an image relationship to a real PNG, gets the recovery "
    "offer stored as `word/header1.xml` (the calibration) and as `word/headerFirst.xml`; so does the main document stored as "
    "`word/main.xml` with the same reference. Word-valid rejects only `word/header1.xml`: the other two are false negatives.",
    "- The same header related by the main document but named by no `w:headerReference` opens clean, with its relationships part and "
    "without one, and so does a glossary document no relationship reaches holding the same reference (as sessions 15 and 35 predicted). "
    "Word-valid rejects all three through `word-part-reference-relationship`: false positives.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at e762ffb5 | strict at e762ffb5 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 51</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 51 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s51builder.mts", ROOT / "s51builder.mts", "ts"), ("compare.py", ROOT / "s51/compare.py", "python"),
                         ("section.py", ROOT / "s51/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s51/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 52: 12:04Z–12:13Z on 2026-10-26, validator columns at 01e4e684

The reference shapes layers 147–150 judge, or explain with a Word sentence, that no earlier session showed Word ([#728](https://github.com/jandira-tech/docx-validate/issues/728): the review of layers 147–150, finding 5, finding 7 and suspected 8, and the first reviewer run's empty ids, hdphoto and theme items). Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 28 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A typed reference naming a relationship of a Type it does not read gets the recovery offer for every shape tried: an `o:OLEObject r:id` naming a `diagramData` relationship, a `c:chart r:id` naming an External `hyperlink` relationship, and a `c:chart r:id` naming `…/relationships/chart/` or `…/relationships/Chart` to a real bar chart that opens clean when the same reference names `…/relationships/chart` (the calibration). Word-valid already rejects all four through `word-part-reference-relationship`.
- An `o:OLEObject r:id` naming an External `package` relationship opens clean; word-valid accepts it.
- An empty id gets the recovery offer in each typed reference: `c:chart r:id=""` and `o:OLEObject r:id=""` (recovery offer), and `dgm:relIds r:dm=""` (an open error with the review's `r:dm`-only element; the recovery offer on session 46's `word-clean-strict01` SmartArt, whose `r:lo`, `r:qs` and `r:cs` stay intact). A `dgm:relIds r:dm` naming an External `diagramData` relationship gets the recovery offer in both shapes. Word-valid accepts all six: false negatives. The `r:dm`-only element is not the cause: `word-clean-strict01` with `dgm:relIds r:dm="rId35"` alone opens clean.
- A chart part with no relationships part, reached only by a Microsoft `hdphoto` relationship that a picture's `a:blip r:embed` names, opens clean, as do the same chart reached only by an image relationship that a `w:name r:id` names or that a VML `v:imagedata r:id` inside a selected `mc:Fallback` names. Word-valid accepts all three.
- A `…/relationships/custom/theme` relationship beside the real theme relationship opens clean, as does one theme; two real theme relationships get the recovery offer. Word-valid agrees on all three: the theme rule's exact-Type count (layer 149) now has its Word row.

| Run    | Observed             | Specimen                                   | Shape                                                                                                         | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 01e4e684                       | strict at 01e4e684                                                                                               |
| ------ | -------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `s52a` | 12:04:32Z, 12:05:01Z | `s52a-control-minimal`                     | control                                                                                                       | `f35b837835c3f7b5` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52a` | 12:04:32Z, 12:05:01Z | `oleobject-names-diagramdata`              | #728 A1: o:OLEObject r:id names a diagramData relationship                                                    | `5b1163d000de8e51` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship`  | invalid: `paraid-missing-element`, `word-part-reference-relationship`                                            |
| `s52a` | 12:04:32Z, 12:05:01Z | `chart-names-external-hyperlink`           | #728 A2: c:chart r:id names an External hyperlink relationship                                                | `200f91f2a7398140` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship`  | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-part-reference-relationship`                       |
| `s52a` | 12:04:32Z, 12:05:01Z | `chart-type-trailing-slash`                | #728 A3: c:chart r:id names …/relationships/chart/ to a real chart                                            | `68cb4a3155075e75` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship`  | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-part-reference-relationship`                       |
| `s52a` | 12:04:32Z, 12:05:01Z | `chart-type-upper-case`                    | #728 A4: c:chart r:id names …/relationships/Chart to a real chart                                             | `a050397a5ac044b4` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship`  | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-part-reference-relationship`                       |
| `s52a` | 12:04:32Z, 12:05:01Z | `chart-type-exact-calibration`             | calibration: c:chart r:id names …/relationships/chart to the same real chart                                  | `e0bde76cbf79fbd2` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`                                                           |
| `s52a` | 12:04:32Z, 12:05:01Z | `oleobject-names-external-package`         | #728 B1: o:OLEObject r:id names an External package relationship                                              | `42b7c8aca543cded` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`                                                           |
| `s52a` | 12:04:32Z, 12:05:01Z | `s52a-control-minimal-end`                 | control                                                                                                       | `f35b837835c3f7b5` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52b` | 12:06:02Z, 12:08:53Z | `s52b-control-minimal`                     | control                                                                                                       | `366bde7ba4f140c4` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52b` | 12:06:02Z, 12:08:53Z | `relids-names-external-diagramdata`        | #728 B2: dgm:relIds r:dm names an External diagramData relationship                                           | `3fef9b9f552516c6` | repair-warning | repair-warning | unreadable-content-warning | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`, `xsd-summary`, `xsd-error`                               |
| `s52b` | 12:06:02Z, 12:08:53Z | `chart-empty-id`                           | #728 C1: c:chart r:id=""                                                                                      | `8812e6ada5e1942f` | repair-warning | repair-warning | unreadable-content-warning | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`                                                           |
| `s52b` | 12:06:02Z, 12:08:53Z | `oleobject-empty-id`                       | #728 C2: o:OLEObject r:id=""                                                                                  | `5deba87fd0cb1ee3` | repair-warning | repair-warning | unreadable-content-warning | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`                                                           |
| `s52b` | 12:06:02Z, 12:08:53Z | `relids-empty-id`                          | #728 C3: dgm:relIds r:dm=""                                                                                   | `9f8ffa8cc45c8707` | open-error     | open-error     | open-error                 | valid                                        | invalid: `rels-unreferenced`, `paraid-missing-element`, `xsd-summary`, `xsd-error`                               |
| `s52b` | 12:06:02Z, 12:08:53Z | `chart-hdphoto-reach-blip-reference`       | #728 D1: word/charts/chart1.xml, no sidecar, reached only by hdphoto rId8 a picture's a:blip r:embed names    | `c962bed520952d95` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                                                      |
| `s52b` | 12:06:02Z, 12:08:53Z | `chart-image-reach-name-reference`         | #728 E1: the same chart reached only by image rId8 a w:name r:id names                                        | `e7baca2a64f19926` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                          |
| `s52b` | 12:06:02Z, 12:08:53Z | `s52b-control-minimal-end`                 | control                                                                                                       | `b2ca6e36f03ceb29` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52c` | 12:09:33Z, 12:09:44Z | `s52c-control-minimal`                     | control                                                                                                       | `b2ca6e36f03ceb29` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52c` | 12:09:33Z, 12:09:44Z | `chart-image-reach-fallback-vml-reference` | #728 E2: the same chart reached only by image rId8 a VML v:imagedata r:id inside a selected mc:Fallback names | `fa2b8cd3fa51e759` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                                                      |
| `s52c` | 12:09:33Z, 12:09:44Z | `theme-one-calibration`                    | calibration: one real theme relationship                                                                      | `132433d2fb230e3e` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52c` | 12:09:33Z, 12:09:44Z | `theme-suffix-only-beside-real`            | #728 F1: …/relationships/custom/theme beside the real theme relationship                                      | `fd4990ea869bf5cc` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52c` | 12:09:33Z, 12:09:44Z | `theme-two-real-calibration`               | #728 F2 calibration: two real theme relationships                                                             | `67529d6209f12d48` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-theme-relationship` | invalid: `word-duplicate-theme-relationship`                                                                     |
| `s52c` | 12:09:33Z, 12:09:44Z | `s52c-control-minimal-end`                 | control                                                                                                       | `b2ca6e36f03ceb29` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52d` | 12:12:42Z, 12:13:35Z | `s52d-control-minimal`                     | control                                                                                                       | `0b77d12fae8479c1` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |
| `s52d` | 12:12:42Z, 12:13:35Z | `strict01-relids-calibration`              | calibration: word-clean-strict01 unmodified (its dgm:relIds names rId35–rId38)                                | `1ba1a977195cf1a1` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                      |
| `s52d` | 12:12:42Z, 12:13:35Z | `strict01-relids-dm-empty`                 | #728 C3 calibrated: word-clean-strict01 with r:dm="" (r:lo, r:qs, r:cs intact)                                | `21263d4829abb864` | repair-warning | repair-warning | unreadable-content-warning | valid                                        | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                      |
| `s52d` | 12:12:42Z, 12:13:35Z | `strict01-relids-dm-external`              | #728 B2 calibrated: word-clean-strict01 with diagramData rId35 External (http://example.com/data1.xml)        | `5363c635fae2f8d8` | repair-warning | repair-warning | unreadable-content-warning | valid                                        | invalid: `rels-unreferenced`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s52d` | 12:12:42Z, 12:13:35Z | `strict01-relids-dm-only`                  | confound: word-clean-strict01 with dgm:relIds r:dm="rId35" alone (no r:lo, r:qs, r:cs)                        | `f1d4859ce527c6c6` | clean-open     | clean-open     | clean-open                 | valid                                        | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                      |
| `s52d` | 12:12:42Z, 12:13:35Z | `s52d-control-minimal-end`                 | control                                                                                                       | `16c76b594ef97d0f` | clean-open     | clean-open     | clean-open                 | valid                                        | valid                                                                                                            |

<details><summary>Raw records, session 52</summary>

```jsonl
{"run": "s52a", "pass": 1, "name": "s52a-control-minimal", "sha256": "f35b837835c3f7b59bca271144bd4ce6374dc77e03b08a4960e95279a941341f", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00007__wfv__s52a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 2, "name": "s52a-control-minimal", "sha256": "f35b837835c3f7b59bca271144bd4ce6374dc77e03b08a4960e95279a941341f", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00007__wfv__s52a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 1, "name": "oleobject-names-diagramdata", "sha256": "5b1163d000de8e51358b26808b1ed7f13c319e99165809ccc21b2937823422c2", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00004__wfv__oleobject-names-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:30.430 'Word found unreadable content in 00004__wfv__oleobject-names-diagramdata.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:31.216 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__oleobject-names-diagramda...)\""]}
{"run": "s52a", "pass": 2, "name": "oleobject-names-diagramdata", "sha256": "5b1163d000de8e51358b26808b1ed7f13c319e99165809ccc21b2937823422c2", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00004__wfv__oleobject-names-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:59.311 'Word found unreadable content in 00004__wfv__oleobject-names-diagramdata.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:05:00.120 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__oleobject-names-diagramda...)\""]}
{"run": "s52a", "pass": 1, "name": "chart-names-external-hyperlink", "sha256": "200f91f2a73981403daab69f08959a0bc4f65b435e6a8f5303e0eeec57193385", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00000__wfv__chart-names-external-hyperlink.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:17.613 'Word found unreadable content in 00000__wfv__chart-names-external-hyperlink.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:18.444 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-names-external-hype...)\""]}
{"run": "s52a", "pass": 2, "name": "chart-names-external-hyperlink", "sha256": "200f91f2a73981403daab69f08959a0bc4f65b435e6a8f5303e0eeec57193385", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00000__wfv__chart-names-external-hyperlink.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:46.778 'Word found unreadable content in 00000__wfv__chart-names-external-hyperlink.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:47.287 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__chart-names-external-hype...)\""]}
{"run": "s52a", "pass": 1, "name": "chart-type-trailing-slash", "sha256": "68cb4a3155075e7534fe501362fe6955d3ac0b82eeeb911cec8b9d9096439208", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00002__wfv__chart-type-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:22.095 'Word found unreadable content in 00002__wfv__chart-type-trailing-slash.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:22.894 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-type-trailing-slash...)\""]}
{"run": "s52a", "pass": 2, "name": "chart-type-trailing-slash", "sha256": "68cb4a3155075e7534fe501362fe6955d3ac0b82eeeb911cec8b9d9096439208", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00002__wfv__chart-type-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:50.995 'Word found unreadable content in 00002__wfv__chart-type-trailing-slash.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:51.746 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-type-trailing-slash...)\""]}
{"run": "s52a", "pass": 1, "name": "chart-type-upper-case", "sha256": "a050397a5ac044b4f26a2dd2b64a549263c1fc7e4064ee41345ce07425873110", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00003__wfv__chart-type-upper-case.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:26.260 'Word found unreadable content in 00003__wfv__chart-type-upper-case.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:27.029 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00003__wfv__chart-type-upper-case.docx)\""]}
{"run": "s52a", "pass": 2, "name": "chart-type-upper-case", "sha256": "a050397a5ac044b4f26a2dd2b64a549263c1fc7e4064ee41345ce07425873110", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00003__wfv__chart-type-upper-case.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:04:55.161 'Word found unreadable content in 00003__wfv__chart-type-upper-case.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:04:55.931 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00003__wfv__chart-type-upper-case.docx)\""]}
{"run": "s52a", "pass": 1, "name": "chart-type-exact-calibration", "sha256": "e0bde76cbf79fbd223ace7aae4ec2f2f9facc7503c2589f32936f67fb260e028", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00001__wfv__chart-type-exact-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-type-exact-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 2, "name": "chart-type-exact-calibration", "sha256": "e0bde76cbf79fbd223ace7aae4ec2f2f9facc7503c2589f32936f67fb260e028", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00001__wfv__chart-type-exact-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-type-exact-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 1, "name": "oleobject-names-external-package", "sha256": "42b7c8aca543cded09a3289211992bb3a5f97089ce0186a6e95ae7aded8067ce", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00005__wfv__oleobject-names-external-package.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF oleobject-names-external-package_byword.pdf (13390 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 2, "name": "oleobject-names-external-package", "sha256": "42b7c8aca543cded09a3289211992bb3a5f97089ce0186a6e95ae7aded8067ce", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00005__wfv__oleobject-names-external-package.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF oleobject-names-external-package_byword.pdf (13390 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 1, "name": "s52a-control-minimal-end", "sha256": "f35b837835c3f7b59bca271144bd4ce6374dc77e03b08a4960e95279a941341f", "observedAt": "2026-10-26T12:04:32+00:00", "staged": "00006__wfv__s52a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52a", "pass": 2, "name": "s52a-control-minimal-end", "sha256": "f35b837835c3f7b59bca271144bd4ce6374dc77e03b08a4960e95279a941341f", "observedAt": "2026-10-26T12:05:01+00:00", "staged": "00006__wfv__s52a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 1, "name": "s52b-control-minimal", "sha256": "366bde7ba4f140c473140de90a7bf2cdc3a709fb6b37030c3dd8249df590f1e2", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00007__wfv__s52b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 2, "name": "s52b-control-minimal", "sha256": "366bde7ba4f140c473140de90a7bf2cdc3a709fb6b37030c3dd8249df590f1e2", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00007__wfv__s52b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 1, "name": "relids-names-external-diagramdata", "sha256": "3fef9b9f552516c62fd435156feffba31b22f67b6c5eba4889b513d48fcd9d90", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00005__wfv__relids-names-external-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:05:30.127 'Word found unreadable content in 00005__wfv__relids-names-external-diagramdata.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:05:30.905 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__relids-names-external-dia...)\""]}
{"run": "s52b", "pass": 2, "name": "relids-names-external-diagramdata", "sha256": "3fef9b9f552516c62fd435156feffba31b22f67b6c5eba4889b513d48fcd9d90", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00005__wfv__relids-names-external-diagramdata.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:08:36.023 \"Word found unreadable content in 00005__wfv__relids-names-external-diagramdata.docx. Do you want to … ? If you trust the source of this document, click Yes.\""]}
{"run": "s52b", "pass": 1, "name": "chart-empty-id", "sha256": "8812e6ada5e1942f8469f0b6928536948f87c44584460c0a7985c2620d2e48c5", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00000__wfv__chart-empty-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:05:17.461 'Word found unreadable content in 00000__wfv__chart-empty-id.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:05:18.237 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00000__wfv__chart-empty-id.docx)\""]}
{"run": "s52b", "pass": 2, "name": "chart-empty-id", "sha256": "8812e6ada5e1942f8469f0b6928536948f87c44584460c0a7985c2620d2e48c5", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00000__wfv__chart-empty-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:06:11.200 'Word found unreadable content in 00000__wfv__chart-empty-id.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:06:11.880 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00000__wfv__chart-empty-id.docx)\""]}
{"run": "s52b", "pass": 1, "name": "oleobject-empty-id", "sha256": "5deba87fd0cb1ee36883ce30eb9cda5b97664b8193efd8280744dc345bb2827b", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00003__wfv__oleobject-empty-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:05:21.796 'Word found unreadable content in 00003__wfv__oleobject-empty-id.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:05:22.562 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00003__wfv__oleobject-empty-id.docx)\""]}
{"run": "s52b", "pass": 2, "name": "oleobject-empty-id", "sha256": "5deba87fd0cb1ee36883ce30eb9cda5b97664b8193efd8280744dc345bb2827b", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00003__wfv__oleobject-empty-id.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:06:28.940 \"Word found unreadable content in 00003__wfv__oleobject-empty-id.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\""]}
{"run": "s52b", "pass": 1, "name": "relids-empty-id", "sha256": "9f8ffa8cc45c87073222486d02d277f28d8fb216a0fc4312b401b720bac4b0d1", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00004__wfv__relids-empty-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 08:05:25.946 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ecovery converter.\\n(00004__wfv__relids-empty-id.docx)'"]}
{"run": "s52b", "pass": 2, "name": "relids-empty-id", "sha256": "9f8ffa8cc45c87073222486d02d277f28d8fb216a0fc4312b401b720bac4b0d1", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00004__wfv__relids-empty-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 08:07:16.002 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th …  Recovery converter. (00004__wfv__relids-empty-id.docx)"]}
{"run": "s52b", "pass": 1, "name": "chart-hdphoto-reach-blip-reference", "sha256": "c962bed520952d95d59c8adaa6e6bc26f496583ac1ca10dfb05c4d9a6ad63e4f", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00001__wfv__chart-hdphoto-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-hdphoto-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 2, "name": "chart-hdphoto-reach-blip-reference", "sha256": "c962bed520952d95d59c8adaa6e6bc26f496583ac1ca10dfb05c4d9a6ad63e4f", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00001__wfv__chart-hdphoto-reach-blip-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-hdphoto-reach-blip-reference_byword.pdf (21332 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 1, "name": "chart-image-reach-name-reference", "sha256": "e7baca2a64f1992678d9a036512a51eceb2ee03431f252c19f516346a7133f1f", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00002__wfv__chart-image-reach-name-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-image-reach-name-reference_byword.pdf (14410 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 2, "name": "chart-image-reach-name-reference", "sha256": "e7baca2a64f1992678d9a036512a51eceb2ee03431f252c19f516346a7133f1f", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00002__wfv__chart-image-reach-name-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-image-reach-name-reference_byword.pdf (14410 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 1, "name": "s52b-control-minimal-end", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:06:02+00:00", "staged": "00006__wfv__s52b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52b", "pass": 2, "name": "s52b-control-minimal-end", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:08:53+00:00", "staged": "00006__wfv__s52b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 1, "name": "s52c-control-minimal", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00002__wfv__s52c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 2, "name": "s52c-control-minimal", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00002__wfv__s52c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 1, "name": "chart-image-reach-fallback-vml-reference", "sha256": "fa2b8cd3fa51e759b222f5c11cb4f97dbb9c8109c02f2bd8ae2e0624477d99c8", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00000__wfv__chart-image-reach-fallback-vml-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-image-reach-fallback-vml-reference_byword.pdf (21462 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 2, "name": "chart-image-reach-fallback-vml-reference", "sha256": "fa2b8cd3fa51e759b222f5c11cb4f97dbb9c8109c02f2bd8ae2e0624477d99c8", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00000__wfv__chart-image-reach-fallback-vml-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-image-reach-fallback-vml-reference_byword.pdf (21462 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 1, "name": "theme-one-calibration", "sha256": "132433d2fb230e3e198ba04015fcb92191fcf487ea23d606dae2ae4d7cba80b6", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00003__wfv__theme-one-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF theme-one-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 2, "name": "theme-one-calibration", "sha256": "132433d2fb230e3e198ba04015fcb92191fcf487ea23d606dae2ae4d7cba80b6", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00003__wfv__theme-one-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF theme-one-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 1, "name": "theme-suffix-only-beside-real", "sha256": "fd4990ea869bf5cc33f0e7658db4f46e05cfbad4916cf406050b748159e4a63a", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00004__wfv__theme-suffix-only-beside-real.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF theme-suffix-only-beside-real_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 2, "name": "theme-suffix-only-beside-real", "sha256": "fd4990ea869bf5cc33f0e7658db4f46e05cfbad4916cf406050b748159e4a63a", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00004__wfv__theme-suffix-only-beside-real.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF theme-suffix-only-beside-real_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 1, "name": "theme-two-real-calibration", "sha256": "67529d6209f12d48345cfa657eadd2214afa0a14dcb308eb6f5a7d6c61376f21", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00005__wfv__theme-two-real-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:09:32.179 'Word found unreadable content in 00005__wfv__theme-two-real-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:09:33.057 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__theme-two-real-calibratio...)\""]}
{"run": "s52c", "pass": 2, "name": "theme-two-real-calibration", "sha256": "67529d6209f12d48345cfa657eadd2214afa0a14dcb308eb6f5a7d6c61376f21", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00005__wfv__theme-two-real-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:09:43.812 'Word found unreadable content in 00005__wfv__theme-two-real-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:09:44.699 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__theme-two-real-calibratio...)\""]}
{"run": "s52c", "pass": 1, "name": "s52c-control-minimal-end", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:09:33+00:00", "staged": "00001__wfv__s52c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52c", "pass": 2, "name": "s52c-control-minimal-end", "sha256": "b2ca6e36f03ceb296a6c1fa41c31182241c6fe6c77a89153031850f1629161c5", "observedAt": "2026-10-26T12:09:44+00:00", "staged": "00001__wfv__s52c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 1, "name": "s52d-control-minimal", "sha256": "0b77d12fae8479c1f9506fe69bc750416b18068b0f4366654a5bbb6944df5e8b", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00001__wfv__s52d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 2, "name": "s52d-control-minimal", "sha256": "0b77d12fae8479c1f9506fe69bc750416b18068b0f4366654a5bbb6944df5e8b", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00001__wfv__s52d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 1, "name": "strict01-relids-calibration", "sha256": "1ba1a977195cf1a1ab83b7037e782b7a4be4323086035f2bd5c503953ca6e1ac", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00002__wfv__strict01-relids-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 2, "name": "strict01-relids-calibration", "sha256": "1ba1a977195cf1a1ab83b7037e782b7a4be4323086035f2bd5c503953ca6e1ac", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00002__wfv__strict01-relids-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 1, "name": "strict01-relids-dm-empty", "sha256": "21263d4829abb86458142dd23539a8cf928c6b8396e811b3bf2def32480d4109", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00003__wfv__strict01-relids-dm-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:11:07.037 'Word found unreadable content in 00003__wfv__strict01-relids-dm-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:11:12.956 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__strict01-relids-dm-empty....)\""]}
{"run": "s52d", "pass": 2, "name": "strict01-relids-dm-empty", "sha256": "21263d4829abb86458142dd23539a8cf928c6b8396e811b3bf2def32480d4109", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00003__wfv__strict01-relids-dm-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:12:59.914 'Word found unreadable content in 00003__wfv__strict01-relids-dm-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 08:13:00.863 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__strict01-relids-dm-empty....)\""]}
{"run": "s52d", "pass": 1, "name": "strict01-relids-dm-external", "sha256": "5363c635fae2f8d875eeed56ebda44bb14e26b4e3459e079b6e940a86bac7520", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00004__wfv__strict01-relids-dm-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:12:07.337 Microsoft Word, Word found unreadable content in 00004__wfv__strict01-relids-dm-external.docx. Do yo … t? If you trust the source of this document, click Yes."]}
{"run": "s52d", "pass": 2, "name": "strict01-relids-dm-external", "sha256": "5363c635fae2f8d875eeed56ebda44bb14e26b4e3459e079b6e940a86bac7520", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00004__wfv__strict01-relids-dm-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 08:13:22.165 \"Word found unreadable content in 00004__wfv__strict01-relids-dm-external.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\"", "2026-10-26 08:13:34.994 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-relids-dm-extern...)\""]}
{"run": "s52d", "pass": 1, "name": "strict01-relids-dm-only", "sha256": "f1d4859ce527c6c69e5d09de3581c6f29017e6d716f80a77f08b089437d11733", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00005__wfv__strict01-relids-dm-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-dm-only_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 2, "name": "strict01-relids-dm-only", "sha256": "f1d4859ce527c6c69e5d09de3581c6f29017e6d716f80a77f08b089437d11733", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00005__wfv__strict01-relids-dm-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-relids-dm-only_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 1, "name": "s52d-control-minimal-end", "sha256": "16c76b594ef97d0f584342e0a1ef30ef4229fcb34a00ed5bc719cba56cba885d", "observedAt": "2026-10-26T12:12:42+00:00", "staged": "00000__wfv__s52d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s52d", "pass": 2, "name": "s52d-control-minimal-end", "sha256": "16c76b594ef97d0f584342e0a1ef30ef4229fcb34a00ed5bc719cba56cba885d", "observedAt": "2026-10-26T12:13:35+00:00", "staged": "00000__wfv__s52d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s52d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 52 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s52builder.mts`:

```ts
// Session 52 (2026-10-26): the shapes #728 asks Word about — reference shapes layers 147–150 judge, or explain with a
// Word sentence, that no session showed Word (the review of layers 147–150: finding 5, finding 7, suspected 8, and
// the first reviewer run's empty ids, hdphoto and theme items).
// - s52a: a typed reference naming a relationship Word was never shown under it (A1–A4), the exact-Type chart
//   calibration, and an External `package` relationship an `o:OLEObject` names (B1);
// - s52b: an External `diagramData` relationship `dgm:relIds r:dm` names (B2), empty ids (C1–C3), an `hdphoto` reach
//   a picture's `a:blip r:embed` names (D1), and an image reach a `w:name r:id` names (E1);
// - s52c: an image reach a VML picture inside a selected `mc:Fallback` names (E2), and theme duplicates counted by
//   exact Type (F1, with one theme and two real themes as calibrations).
// - s52d: s52b's `dgm:relIds` carried only `r:dm` (the review's shape), which the schema refuses on its own, so Word's
//   refusal of B2 and C3 was confounded. s52d asks again on session 46's word-clean-strict01 SmartArt, whose
//   `dgm:relIds` names all four parts: unmodified, with `r:dm=""`, with `rId35` made External, and with `r:dm` alone.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s52a pnpm exec tsx s52builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { barChartXml, CHART_CONTENT_TYPE, PICTURE_DRAWING, reachedChartSpecimenParts } from "./tests/support/chart-specimens";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const DGM = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
const O = "urn:schemas-microsoft-com:office:office";
const HDPHOTO = "http://schemas.microsoft.com/office/2007/relationships/hdphoto";
const THEME_CT = "application/vnd.openxmlformats-officedocument.theme+xml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const CHART = "word/charts/chart1.xml";
const P = MINIMAL_PARTS as Record<string, string>;
const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "base64"),
);
const DRAWING_NS = `xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:dgm="${DGM}" xmlns:o="${O}" xmlns:r="${R}"`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, type: string, target: string, external = false) =>
    `<Relationship Id="${id}" Type="${type}" Target="${target}"${external ? ' TargetMode="External"' : ""}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const withTypes = (types: string, defaults: Array<[string, string]>, overrides: Array<[string, string]>) =>
    replaceOnce(
        replaceOnce(
            types,
            '<Default Extension="rels"',
            `${defaults.map(([ext, type]) => `<Default Extension="${ext}" ContentType="${type}"/>`).join("")}<Default Extension="rels"`,
        ),
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The review's drawings (`review-147-150/specimens.ts`), each in its own paragraph. */
const chartDrawing = (id: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart r:id="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const diagramDrawing = (id: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Diagram 1"/><a:graphic><a:graphicData uri="${DGM}">` +
    `<dgm:relIds r:dm="${id}"/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const oleObject = (id: string) =>
    '<w:p><w:r><w:object><o:OLEObject Type="Embed" ProgID="Package" ShapeID="_x0000_i1025" DrawAspect="Icon" ObjectID="_1" ' +
    `r:id="${id}"/></w:object></w:r></w:p>`;
/** The minimal package plus a PNG, `body` before the main document's `w:sectPr`, `relationships` on its sidecar. */
const withBody = (body: string, relationships: string[], extra: Record<string, string> = {}, overrides: Array<[string, string]> = []) =>
    buildDocx({
        ...P,
        "word/media/image1.png": PNG,
        ...extra,
        [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, "<w:document ", `<w:document ${DRAWING_NS} `), "<w:sectPr>", `${body}<w:sectPr>`),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationships.join("")),
        [CT]: withTypes(P[CT]!, [["png", "image/png"]], overrides),
    });
/** A clustered bar chart (no `c:externalData`, so no sidecar) at word/charts/chart1.xml that `c:chart r:id="rId9"` names as `type`. */
const barChartNamedAs = (type: string) =>
    withBody(chartDrawing("rId9"), [relationship("rId9", type, "charts/chart1.xml")], { [CHART]: barChartXml(false) }, [
        [CHART, CHART_CONTENT_TYPE],
    ]);

const W14_PARAGRAPH = '<w:p w14:paraId="00000002" w14:textId="00000002">';
const VML_PICTURE =
    `${W14_PARAGRAPH}<w:r><w:pict><v:shape xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="${O}" id="s1" style="width:10pt;height:10pt">` +
    '<v:imagedata r:id="rId8" o:title=""/></v:shape></w:pict></w:r></w:p>';
const NAME_REFERENCE = `${W14_PARAGRAPH}<w:name r:id="rId8"/><w:r><w:t>x</w:t></w:r></w:p>`;
/** The review's attack150 reach: the bare chart (dangling `c:externalData`, no sidecar) reached only as `type` `rId8`. */
const reach = (type: string, drawing: string) => buildDocx(reachedChartSpecimenParts(CHART, [{ id: "rId8", type }], drawing));
const fallbackVml = () => {
    const parts = reachedChartSpecimenParts(
        CHART,
        [{ id: "rId8", type: `${R}/image` }],
        `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>${VML_PICTURE}</mc:Fallback></mc:AlternateContent>`,
    );
    parts[MAIN] = replaceOnce(parts[MAIN]!, "<w:document ", '<w:document xmlns:foo="urn:foo" ');
    return buildDocx(parts);
};

/** The theme part of the repository's duplicate-theme fixture, read once. */
let themeXml: string | undefined;
const theme = async () =>
    (themeXml ??= await (
        await JSZip.loadAsync(readFileSync("tests/fixtures/broken/package.word-duplicate-theme.docx"))
    )
        .file("word/theme/theme1.xml")!
        .async("string"));
/** The minimal package plus word/theme/theme1.xml as a real theme and, when `second` is given, word/theme/theme2.xml as `second`. */
const themes = async (second?: string) =>
    buildDocx({
        ...P,
        "word/theme/theme1.xml": await theme(),
        ...(second === undefined ? {} : { "word/theme/theme2.xml": await theme() }),
        [SIDECAR]: appendRels(
            P[SIDECAR]!,
            relationship("rIdT1", `${R}/theme`, "theme/theme1.xml") +
                (second === undefined ? "" : relationship("rIdT2", second, "theme/theme2.xml")),
        ),
        [CT]: withTypes(
            P[CT]!,
            [],
            [
                ["word/theme/theme1.xml", THEME_CT],
                ...(second === undefined ? [] : [["word/theme/theme2.xml", THEME_CT] as [string, string]]),
            ],
        ),
    });
const control = () => buildDocx({ ...P });

/** Session 46's word-clean-strict01 package with `edit` applied to its parts (part name → text). */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (parts: Record<string, string | Uint8Array>, text: (name: string) => string) => void = () => {}) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    edit(parts, (name) => Buffer.from(parts[name] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};
const RELIDS = 'r:dm="rId35" r:lo="rId36" r:qs="rId37" r:cs="rId38"';
const relIdsAs = (to: string) => strict01((parts, text) => void (parts[MAIN] = replaceOnce(text(MAIN), RELIDS, to)));
const DATA_REL =
    '<Relationship Id="rId35" Type="http://purl.oclc.org/ooxml/officeDocument/relationships/diagramData" Target="diagrams/data1.xml"/>';
const externalData = () =>
    strict01(
        (parts, text) =>
            void (parts[SIDECAR] = replaceOnce(
                text(SIDECAR),
                DATA_REL,
                DATA_REL.replace('Target="diagrams/data1.xml"/>', 'Target="http://example.com/data1.xml" TargetMode="External"/>'),
            )),
    );

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s52a: [
        ["s52a-control-minimal", "control", control],
        [
            "oleobject-names-diagramdata",
            "#728 A1: o:OLEObject r:id names a diagramData relationship",
            () => withBody(oleObject("rId9"), [relationship("rId9", `${R}/diagramData`, "media/image1.png")]),
        ],
        [
            "chart-names-external-hyperlink",
            "#728 A2: c:chart r:id names an External hyperlink relationship",
            () => withBody(chartDrawing("rId9"), [relationship("rId9", `${R}/hyperlink`, "http://example.com/", true)]),
        ],
        [
            "chart-type-trailing-slash",
            "#728 A3: c:chart r:id names …/relationships/chart/ to a real chart",
            () => barChartNamedAs(`${R}/chart/`),
        ],
        ["chart-type-upper-case", "#728 A4: c:chart r:id names …/relationships/Chart to a real chart", () => barChartNamedAs(`${R}/Chart`)],
        [
            "chart-type-exact-calibration",
            "calibration: c:chart r:id names …/relationships/chart to the same real chart",
            () => barChartNamedAs(`${R}/chart`),
        ],
        [
            "oleobject-names-external-package",
            "#728 B1: o:OLEObject r:id names an External package relationship",
            () => withBody(oleObject("rId9"), [relationship("rId9", `${R}/package`, "http://example.com/o.xlsx", true)]),
        ],
        ["s52a-control-minimal-end", "control", control],
    ],
    s52b: [
        ["s52b-control-minimal", "control", control],
        [
            "relids-names-external-diagramdata",
            "#728 B2: dgm:relIds r:dm names an External diagramData relationship",
            () => withBody(diagramDrawing("rId9"), [relationship("rId9", `${R}/diagramData`, "http://example.com/data1.xml", true)]),
        ],
        ["chart-empty-id", '#728 C1: c:chart r:id=""', () => withBody(chartDrawing(""), [])],
        ["oleobject-empty-id", '#728 C2: o:OLEObject r:id=""', () => withBody(oleObject(""), [])],
        ["relids-empty-id", '#728 C3: dgm:relIds r:dm=""', () => withBody(diagramDrawing(""), [])],
        [
            "chart-hdphoto-reach-blip-reference",
            "#728 D1: word/charts/chart1.xml, no sidecar, reached only by hdphoto rId8 a picture's a:blip r:embed names",
            () => reach(HDPHOTO, PICTURE_DRAWING),
        ],
        [
            "chart-image-reach-name-reference",
            "#728 E1: the same chart reached only by image rId8 a w:name r:id names",
            () => reach(`${R}/image`, NAME_REFERENCE),
        ],
        ["s52b-control-minimal-end", "control", control],
    ],
    s52c: [
        ["s52c-control-minimal", "control", control],
        [
            "chart-image-reach-fallback-vml-reference",
            "#728 E2: the same chart reached only by image rId8 a VML v:imagedata r:id inside a selected mc:Fallback names",
            fallbackVml,
        ],
        ["theme-one-calibration", "calibration: one real theme relationship", () => themes()],
        [
            "theme-suffix-only-beside-real",
            "#728 F1: …/relationships/custom/theme beside the real theme relationship",
            () => themes(`${R}/custom/theme`),
        ],
        ["theme-two-real-calibration", "#728 F2 calibration: two real theme relationships", () => themes(`${R}/theme`)],
        ["s52c-control-minimal-end", "control", control],
    ],
    s52d: [
        ["s52d-control-minimal", "control", control],
        ["strict01-relids-calibration", "calibration: word-clean-strict01 unmodified (its dgm:relIds names rId35–rId38)", () => strict01()],
        [
            "strict01-relids-dm-empty",
            '#728 C3 calibrated: word-clean-strict01 with r:dm="" (r:lo, r:qs, r:cs intact)',
            () => relIdsAs(RELIDS.replace('r:dm="rId35"', 'r:dm=""')),
        ],
        [
            "strict01-relids-dm-external",
            "#728 B2 calibrated: word-clean-strict01 with diagramData rId35 External (http://example.com/data1.xml)",
            externalData,
        ],
        [
            "strict01-relids-dm-only",
            'confound: word-clean-strict01 with dgm:relIds r:dm="rId35" alone (no r:lo, r:qs, r:cs)',
            () => relIdsAs('r:dm="rId35"'),
        ],
        ["s52d-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-52 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s52a", "s52b", "s52c", "s52d")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s52/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-52 parts of docs/plans/evidence/word-probes-2026-10-24.md into s52/section.md.

Reads the chunk's specimens.jsonl (validator columns at 01e4e684, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s52/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s52a", "s52b", "s52c", "s52d")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s52/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 52: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 01e4e684",
    "",
    "The reference shapes layers 147–150 judge, or explain with a Word sentence, that no earlier session showed Word "
    "([#728](https://github.com/jandira-tech/docx-validate/issues/728): the review of layers 147–150, finding 5, finding 7 and suspected 8, "
    "and the first reviewer run's empty ids, hdphoto and theme items). Each chunk ran twice, as two separate driver runs of byte-identical "
    "copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    "is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 28 rows agree. The two times in Observed "
    "are the ends of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A typed reference naming a relationship of a Type it does not read gets the recovery offer for every shape tried: an `o:OLEObject r:id` "
    "naming a `diagramData` relationship, a `c:chart r:id` naming an External `hyperlink` relationship, and a `c:chart r:id` naming "
    "`…/relationships/chart/` or `…/relationships/Chart` to a real bar chart that opens clean when the same reference names "
    "`…/relationships/chart` (the calibration). Word-valid already rejects all four through `word-part-reference-relationship`.",
    "- An `o:OLEObject r:id` naming an External `package` relationship opens clean; word-valid accepts it.",
    "- An empty id gets the recovery offer in each typed reference: `c:chart r:id=\"\"` and `o:OLEObject r:id=\"\"` (recovery offer), "
    "and `dgm:relIds r:dm=\"\"` (an open error with the review's `r:dm`-only element; the recovery offer on session 46's "
    "`word-clean-strict01` SmartArt, whose `r:lo`, `r:qs` and `r:cs` stay intact). A `dgm:relIds r:dm` naming an External `diagramData` "
    "relationship gets the recovery offer in both shapes. Word-valid accepts all six: false negatives. The `r:dm`-only element is not "
    "the cause: `word-clean-strict01` with `dgm:relIds r:dm=\"rId35\"` alone opens clean.",
    "- A chart part with no relationships part, reached only by a Microsoft `hdphoto` relationship that a picture's `a:blip r:embed` "
    "names, opens clean, as do the same chart reached only by an image relationship that a `w:name r:id` names or that a VML "
    "`v:imagedata r:id` inside a selected `mc:Fallback` names. Word-valid accepts all three.",
    "- A `…/relationships/custom/theme` relationship beside the real theme relationship opens clean, as does one theme; two real theme "
    "relationships get the recovery offer. Word-valid agrees on all three: the theme rule's exact-Type count (layer 149) now has its "
    "Word row.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 01e4e684 | strict at 01e4e684 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 52</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 52 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s52builder.mts", ROOT / "s52builder.mts", "ts"), ("compare.py", ROOT / "s52/compare.py", "python"),
                         ("section.py", ROOT / "s52/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s52/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 53: 13:21Z–13:33Z on 2026-10-26, validator columns at 0b26c414

The content-type shapes the review of layers 156–160 says those layers judge, or explain with a session, that no earlier session showed Word ([#739](https://github.com/jandira-tech/docx-validate/issues/739): a second relationship to an eagerly read part; [#740](https://github.com/jandira-tech/docx-validate/issues/740): the spellings and types the recovery sentence cites a session for). Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 64 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The part bodies are session 47's empty roots.

- A footer relationship the body references (`w:footerReference`) whose target is the main document, the related numbering part or the styles part gets the recovery offer, typed with its own type (the calibrations) and typed with session 49's and 50's refused types alike. So does `word/styles.xml` when the main document's settings relationship also targets it, typed styles or typed settings. Word-valid accepts all eight: false negatives, and the review's shapes are refused whatever the Override says.
- `word/settings.xml`, `word/fontTable.xml` and `word/numbering.xml`, related by the main document, get the recovery offer typed `APPLICATION/OCTET-STREAM`, `application/octet-stream; charset=utf-8`, `image/png` or `application/foo+xml` (session 50 showed `application/octet-stream` only). Word-valid rejects all twelve.
- The main document gets the recovery offer typed with the theme, glossary, header, footer, footnotes, endnotes, comments, settings, fontTable or numbering content type (session 50 showed the styles type only); word-valid rejects all ten.
- A related settings part typed with the main document, numbering, header, fontTable, theme or comments type, a related numbering part typed with the main document, styles, header, fontTable or comments type, and the styles part typed with the main document, numbering, header, fontTable, theme or comments type all get the recovery offer; word-valid rejects all sixteen.
- A related numbering part whose Override has `ContentType=""` gets the recovery offer, as styles (session 49) and settings and fontTable (session 50) did. Word-valid accepts it: a false negative.

| Run    | Observed             | Specimen                                 | Shape                                                                                                               | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 0b26c414                         | strict at 0b26c414                             |
| ------ | -------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------------------- | ---------------------------------------------- |
| `s53a` | 13:21:40Z, 13:28:57Z | `s53a-control-minimal`                   | control                                                                                                             | `e188dbb6b25b9d81` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-main-calibration`        | #739 calibration: a footer relationship the body references targets word/document.xml, typed main                   | `ca276870e63588a6` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-main-styles-type`        | #739: the same, the main document typed with the styles content type                                                | `74518ae2db909694` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-numbering-calibration`   | #739 calibration: a footer relationship the body references targets the related word/numbering.xml, typed numbering | `ade633ca0639dab9` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-numbering-settings-type` | #739: the same, numbering typed with the settings content type                                                      | `c560c8a0161ae53b` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-styles-calibration`      | #739 calibration: a footer relationship the body references targets word/styles.xml, typed styles                   | `b8a71216d9c7317c` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `coreach-footer-styles-settings-type`    | #739: the same, styles typed with the settings content type                                                         | `1eaeb5e83687f43b` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `word-part-content-type-mismatch`     |
| `s53a` | 13:21:40Z, 13:28:57Z | `s53a-control-minimal-end`               | control                                                                                                             | `e188dbb6b25b9d81` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53b` | 13:23:39Z, 13:29:41Z | `s53b-control-minimal`                   | control                                                                                                             | `c940ba0a774cf4d6` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53b` | 13:23:39Z, 13:29:41Z | `coreach-settings-styles-calibration`    | #739 calibration: word/styles.xml is also the target of the main document's settings relationship, typed styles     | `593e55d8b335ede0` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | valid                                          |
| `s53b` | 13:23:39Z, 13:29:41Z | `coreach-settings-styles-settings-type`  | #739 (review S5): the same, styles typed with the settings content type                                             | `36ad5effbec5074c` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | valid                                          |
| `s53b` | 13:23:39Z, 13:29:41Z | `settings-override-octet-upper`          | #740: a related word/settings.xml typed APPLICATION/OCTET-STREAM                                                    | `a8edd982bd14752a` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53b` | 13:23:39Z, 13:29:41Z | `settings-override-octet-charset`        | #740: a related word/settings.xml typed application/octet-stream; charset=utf-8                                     | `8ba5edba8249e1dc` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53b` | 13:23:39Z, 13:29:41Z | `settings-override-image-png`            | #740: a related word/settings.xml typed image/png                                                                   | `9eace5a5a1043a87` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53b` | 13:23:39Z, 13:29:41Z | `settings-override-foo-xml`              | #740: a related word/settings.xml typed application/foo+xml                                                         | `b1316d93ceaed750` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53b` | 13:23:39Z, 13:29:41Z | `s53b-control-minimal-end`               | control                                                                                                             | `c940ba0a774cf4d6` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53c` | 13:24:49Z, 13:30:41Z | `s53c-control-minimal`                   | control                                                                                                             | `c940ba0a774cf4d6` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53c` | 13:24:49Z, 13:30:41Z | `fonttable-override-octet-upper`         | #740: a related word/fontTable.xml typed APPLICATION/OCTET-STREAM                                                   | `6a5fe4cb9971efdf` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `fonttable-override-octet-charset`       | #740: a related word/fontTable.xml typed application/octet-stream; charset=utf-8                                    | `72aae2c806d3aa78` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `fonttable-override-image-png`           | #740: a related word/fontTable.xml typed image/png                                                                  | `2bca23dddba2ee04` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `fonttable-override-foo-xml`             | #740: a related word/fontTable.xml typed application/foo+xml                                                        | `0b3a6d1e58e37ca2` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `numbering-override-octet-upper`         | #740: a related word/numbering.xml typed APPLICATION/OCTET-STREAM                                                   | `31b408bd8cab0d9a` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `numbering-override-octet-charset`       | #740: a related word/numbering.xml typed application/octet-stream; charset=utf-8                                    | `e9a7a6ba6158d91f` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53c` | 13:24:49Z, 13:30:41Z | `s53c-control-minimal-end`               | control                                                                                                             | `78e76aaf80e6ac15` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53d` | 13:25:34Z, 13:31:13Z | `s53d-control-minimal`                   | control                                                                                                             | `78e76aaf80e6ac15` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53d` | 13:25:34Z, 13:31:13Z | `numbering-override-image-png`           | #740: a related word/numbering.xml typed image/png                                                                  | `12dc7dd7f7cedc9e` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53d` | 13:25:34Z, 13:31:13Z | `numbering-override-foo-xml`             | #740: a related word/numbering.xml typed application/foo+xml                                                        | `b752b67489a90049` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-unrecognized` | invalid: `word-part-content-type-unrecognized` |
| `s53d` | 13:25:34Z, 13:31:13Z | `numbering-override-empty`               | #740: a related word/numbering.xml whose Override has ContentType=""                                                | `cc4ec9114d116472` | repair-warning | repair-warning | unreadable-content-warning | valid                                          | invalid: `xsd-summary`, `xsd-error`            |
| `s53d` | 13:25:34Z, 13:31:13Z | `main-override-theme-type`               | #740: main document Override typed with the theme content type                                                      | `ebefeb7701b17ebb` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53d` | 13:25:34Z, 13:31:13Z | `main-override-glossary-type`            | #740: main document Override typed with the glossary content type                                                   | `e920b88eef248648` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53d` | 13:25:34Z, 13:31:13Z | `main-override-header-type`              | #740: main document Override typed with the header content type                                                     | `d324da4b33f07bb6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53d` | 13:25:34Z, 13:31:13Z | `s53d-control-minimal-end`               | control                                                                                                             | `78e76aaf80e6ac15` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53e` | 13:26:19Z, 13:32:08Z | `s53e-control-minimal`                   | control                                                                                                             | `78e76aaf80e6ac15` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-footer-type`              | #740: main document Override typed with the footer content type                                                     | `4811c413899302e1` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-footnotes-type`           | #740: main document Override typed with the footnotes content type                                                  | `7499826e8dc67598` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-endnotes-type`            | #740: main document Override typed with the endnotes content type                                                   | `e0871228afc1668e` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-comments-type`            | #740: main document Override typed with the comments content type                                                   | `2fa2a70a1e893533` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-settings-type`            | #740: main document Override typed with the settings content type                                                   | `dcd93adbd0025cf6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `main-override-fonttable-type`           | #740: main document Override typed with the fontTable content type                                                  | `541c386fdada46d5` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53e` | 13:26:19Z, 13:32:08Z | `s53e-control-minimal-end`               | control                                                                                                             | `23b03320df4545d9` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53f` | 13:26:51Z, 13:32:55Z | `s53f-control-minimal`                   | control                                                                                                             | `23b03320df4545d9` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53f` | 13:26:51Z, 13:32:55Z | `main-override-numbering-type`           | #740: main document Override typed with the numbering content type                                                  | `2dae93e99250fb43` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `settings-override-main-type`            | #740: a related word/settings.xml typed with the main content type                                                  | `df98b34b70226d9f` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `settings-override-numbering-type`       | #740: a related word/settings.xml typed with the numbering content type                                             | `d4036be15f4fc7c6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `settings-override-header-type`          | #740: a related word/settings.xml typed with the header content type                                                | `79be997fffbbe994` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `settings-override-fonttable-type`       | #740: a related word/settings.xml typed with the fontTable content type                                             | `f5e9f34ea9425832` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `settings-override-theme-type`           | #740: a related word/settings.xml typed with the theme content type                                                 | `118618eee67d9e9b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53f` | 13:26:51Z, 13:32:55Z | `s53f-control-minimal-end`               | control                                                                                                             | `23b03320df4545d9` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53g` | 13:27:22Z, 13:33:25Z | `s53g-control-minimal`                   | control                                                                                                             | `8ac6bfb91e63af67` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53g` | 13:27:22Z, 13:33:25Z | `numbering-override-main-type`           | #740: a related word/numbering.xml typed with the main content type                                                 | `7832b5bb17d01ed1` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `numbering-override-styles-type`         | #740: a related word/numbering.xml typed with the styles content type                                               | `ba3fd57cde8be733` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `numbering-override-header-type`         | #740: a related word/numbering.xml typed with the header content type                                               | `fb80d2781713f31f` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `numbering-override-fonttable-type`      | #740: a related word/numbering.xml typed with the fontTable content type                                            | `94cea678ac00ff52` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `styles-override-main-type`              | #740: word/styles.xml typed with the main content type                                                              | `bf1aa82ed7094c97` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `styles-override-numbering-type`         | #740: word/styles.xml typed with the numbering content type                                                         | `0ffdb42bd74bb2ba` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53g` | 13:27:22Z, 13:33:25Z | `s53g-control-minimal-end`               | control                                                                                                             | `8ac6bfb91e63af67` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53h` | 13:28:07Z, 13:33:54Z | `s53h-control-minimal`                   | control                                                                                                             | `8ac6bfb91e63af67` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |
| `s53h` | 13:28:07Z, 13:33:54Z | `styles-override-header-type`            | #740: word/styles.xml typed with the header content type                                                            | `3e2a3416cd854035` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `styles-override-fonttable-type`         | #740: word/styles.xml typed with the fontTable content type                                                         | `a0659f53f2004119` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `styles-override-theme-type`             | #740: word/styles.xml typed with the theme content type                                                             | `b9780a86f257f176` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `styles-override-comments-type`          | #740: word/styles.xml typed with the comments content type                                                          | `0075019d042984a3` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `settings-override-comments-type`        | #740: a related word/settings.xml typed with the comments content type                                              | `a6b36c64a0c32435` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `numbering-override-comments-type`       | #740: a related word/numbering.xml typed with the comments content type                                             | `aff30486f65c81c6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`     | invalid: `word-part-content-type-mismatch`     |
| `s53h` | 13:28:07Z, 13:33:54Z | `s53h-control-minimal-end`               | control                                                                                                             | `54ee4a813779f3b6` | clean-open     | clean-open     | clean-open                 | valid                                          | valid                                          |

<details><summary>Raw records, session 53</summary>

```jsonl
{"run": "s53a", "pass": 1, "name": "s53a-control-minimal", "sha256": "e188dbb6b25b9d81e9381e9a276dad5b10a4e65883c181f6934c53f212d6f0c9", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00007__wfv__s53a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53a", "pass": 2, "name": "s53a-control-minimal", "sha256": "e188dbb6b25b9d81e9381e9a276dad5b10a4e65883c181f6934c53f212d6f0c9", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00007__wfv__s53a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-main-calibration", "sha256": "ca276870e63588a6d0a088d59381d5486bc59fb7911134d9ec0daaaf46148c07", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00000__wfv__coreach-footer-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:20:29.074 'Word found unreadable content in 00000__wfv__coreach-footer-main-calibration.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:20:29.818 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__coreach-footer-main-calib...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-main-calibration", "sha256": "ca276870e63588a6d0a088d59381d5486bc59fb7911134d9ec0daaaf46148c07", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00000__wfv__coreach-footer-main-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:25.919 'Word found unreadable content in 00000__wfv__coreach-footer-main-calibration.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:26.773 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__coreach-footer-main-calib...)\""]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-main-styles-type", "sha256": "74518ae2db909694f4d5d808bbf16d47d9e40c12b43402a31ef0a51ab02244c1", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00001__wfv__coreach-footer-main-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:21:17.434 'Word found unreadable content in 00001__wfv__coreach-footer-main-styles-type.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:21:18.036 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__coreach-footer-main-style...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-main-styles-type", "sha256": "74518ae2db909694f4d5d808bbf16d47d9e40c12b43402a31ef0a51ab02244c1", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00001__wfv__coreach-footer-main-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:33.765 'Word found unreadable content in 00001__wfv__coreach-footer-main-styles-type.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:34.655 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__coreach-footer-main-style...)\""]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-numbering-calibration", "sha256": "ade633ca0639dab9ef3dc1837df3501c80e606a083f653b92916470bf11da3d8", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00002__wfv__coreach-footer-numbering-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:21:22.784 'Word found unreadable content in 00002__wfv__coreach-footer-numbering-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:21:23.386 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__coreach-footer-numbering-...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-numbering-calibration", "sha256": "ade633ca0639dab9ef3dc1837df3501c80e606a083f653b92916470bf11da3d8", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00002__wfv__coreach-footer-numbering-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:42.780 'Word found unreadable content in 00002__wfv__coreach-footer-numbering-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:43.685 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__coreach-footer-numbering-...)\""]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-numbering-settings-type", "sha256": "c560c8a0161ae53bf888e8039a0bba021de179b11ec79f60f888aedfb4b6de99", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00003__wfv__coreach-footer-numbering-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:21:27.516 'Word found unreadable content in 00003__wfv__coreach-footer-numbering-settings-type.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:21:28.054 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__coreach-footer-numbering-...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-numbering-settings-type", "sha256": "c560c8a0161ae53bf888e8039a0bba021de179b11ec79f60f888aedfb4b6de99", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00003__wfv__coreach-footer-numbering-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:47.083 'Word found unreadable content in 00003__wfv__coreach-footer-numbering-settings-type.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:47.982 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__coreach-footer-numbering-...)\""]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-styles-calibration", "sha256": "b8a71216d9c7317c230d79658da3226301110a9ddb343c74fcc412179bb378d0", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00004__wfv__coreach-footer-styles-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:21:33.651 'Word found unreadable content in 00004__wfv__coreach-footer-styles-calibration.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:21:34.303 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__coreach-footer-styles-cal...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-styles-calibration", "sha256": "b8a71216d9c7317c230d79658da3226301110a9ddb343c74fcc412179bb378d0", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00004__wfv__coreach-footer-styles-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:51.362 'Word found unreadable content in 00004__wfv__coreach-footer-styles-calibration.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:52.269 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__coreach-footer-styles-cal...)\""]}
{"run": "s53a", "pass": 1, "name": "coreach-footer-styles-settings-type", "sha256": "1eaeb5e83687f43b29cc5e7e78ad614a3a0977b86c5e99eeb0fcb1251b3c0599", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00005__wfv__coreach-footer-styles-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:21:38.417 'Word found unreadable content in 00005__wfv__coreach-footer-styles-settings-type.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:21:38.987 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__coreach-footer-styles-set...)\""]}
{"run": "s53a", "pass": 2, "name": "coreach-footer-styles-settings-type", "sha256": "1eaeb5e83687f43b29cc5e7e78ad614a3a0977b86c5e99eeb0fcb1251b3c0599", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00005__wfv__coreach-footer-styles-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:55.583 'Word found unreadable content in 00005__wfv__coreach-footer-styles-settings-type.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:56.500 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__coreach-footer-styles-set...)\""]}
{"run": "s53a", "pass": 1, "name": "s53a-control-minimal-end", "sha256": "e188dbb6b25b9d81e9381e9a276dad5b10a4e65883c181f6934c53f212d6f0c9", "observedAt": "2026-10-26T13:21:40+00:00", "staged": "00006__wfv__s53a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53a", "pass": 2, "name": "s53a-control-minimal-end", "sha256": "e188dbb6b25b9d81e9381e9a276dad5b10a4e65883c181f6934c53f212d6f0c9", "observedAt": "2026-10-26T13:28:57+00:00", "staged": "00006__wfv__s53a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53b", "pass": 1, "name": "s53b-control-minimal", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00003__wfv__s53b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53b", "pass": 2, "name": "s53b-control-minimal", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00003__wfv__s53b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53b", "pass": 1, "name": "coreach-settings-styles-calibration", "sha256": "593e55d8b335ede0eea1a150d55e170d67ba3419283aec6ca4a732e6f43906cf", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00000__wfv__coreach-settings-styles-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:22:03.216 'Word found unreadable content in 00000__wfv__coreach-settings-styles-calibration.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:22:04.063 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__coreach-settings-styles-c...)\""]}
{"run": "s53b", "pass": 2, "name": "coreach-settings-styles-calibration", "sha256": "593e55d8b335ede0eea1a150d55e170d67ba3419283aec6ca4a732e6f43906cf", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00000__wfv__coreach-settings-styles-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:06.279 'Word found unreadable content in 00000__wfv__coreach-settings-styles-calibration.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:07.136 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__coreach-settings-styles-c...)\""]}
{"run": "s53b", "pass": 1, "name": "coreach-settings-styles-settings-type", "sha256": "36ad5effbec5074c10e4928c5a09311ef38403b0d26ec5d47a0d7c84cca5b249", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00001__wfv__coreach-settings-styles-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:05.773 Microsoft Word, Word found unreadable content in 00001__wfv__coreach-settings-styles-settings-type.d … t? If you trust the source of this document, click Yes."]}
{"run": "s53b", "pass": 2, "name": "coreach-settings-styles-settings-type", "sha256": "36ad5effbec5074c10e4928c5a09311ef38403b0d26ec5d47a0d7c84cca5b249", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00001__wfv__coreach-settings-styles-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:14.914 'Word found unreadable content in 00001__wfv__coreach-settings-styles-settings-type.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:15.564 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__coreach-settings-styles-s...)\""]}
{"run": "s53b", "pass": 1, "name": "settings-override-octet-upper", "sha256": "a8edd982bd14752a18005ac5ab31509599a326ed14ebaa4044921afa5864b662", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00007__wfv__settings-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:38.548 'Word found unreadable content in 00007__wfv__settings-override-octet-upper.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:23:39.444 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-octet-u...)\""]}
{"run": "s53b", "pass": 2, "name": "settings-override-octet-upper", "sha256": "a8edd982bd14752a18005ac5ab31509599a326ed14ebaa4044921afa5864b662", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00007__wfv__settings-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:40.650 'Word found unreadable content in 00007__wfv__settings-override-octet-upper.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:41.190 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-octet-u...)\""]}
{"run": "s53b", "pass": 1, "name": "settings-override-octet-charset", "sha256": "8ba5edba8249e1dce6333e377356554f9b33d75126ee34884439e75e851a89eb", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00006__wfv__settings-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:34.201 'Word found unreadable content in 00006__wfv__settings-override-octet-charset.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:23:34.879 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-octet-c...)\""]}
{"run": "s53b", "pass": 2, "name": "settings-override-octet-charset", "sha256": "8ba5edba8249e1dce6333e377356554f9b33d75126ee34884439e75e851a89eb", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00006__wfv__settings-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:32.580 'Word found unreadable content in 00006__wfv__settings-override-octet-charset.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:33.247 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-octet-c...)\""]}
{"run": "s53b", "pass": 1, "name": "settings-override-image-png", "sha256": "9eace5a5a1043a87aa9e1c8ccde071ea565690ef828136084af646583f5be2cc", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00005__wfv__settings-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:24.303 'Word found unreadable content in 00005__wfv__settings-override-image-png.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:23:29.753 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__settings-override-image-p...)\""]}
{"run": "s53b", "pass": 2, "name": "settings-override-image-png", "sha256": "9eace5a5a1043a87aa9e1c8ccde071ea565690ef828136084af646583f5be2cc", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00005__wfv__settings-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:27.279 'Word found unreadable content in 00005__wfv__settings-override-image-png.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:28.198 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__settings-override-image-p...)\""]}
{"run": "s53b", "pass": 1, "name": "settings-override-foo-xml", "sha256": "b1316d93ceaed7505e9538376e52b4ddd27f284bc332052b7fb154793dad6588", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00004__wfv__settings-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:15.541 \"Word found unreadable content in 00004__wfv__settings-override-foo-xml.docx. Do you want to recover … ? If you trust the source of this document, click Yes.\"", "2026-10-26 09:23:15.542 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__settings-override-foo-xml...)\""]}
{"run": "s53b", "pass": 2, "name": "settings-override-foo-xml", "sha256": "b1316d93ceaed7505e9538376e52b4ddd27f284bc332052b7fb154793dad6588", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00004__wfv__settings-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:20.149 'Word found unreadable content in 00004__wfv__settings-override-foo-xml.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:21.031 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__settings-override-foo-xml...)\""]}
{"run": "s53b", "pass": 1, "name": "s53b-control-minimal-end", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:23:39+00:00", "staged": "00002__wfv__s53b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53b", "pass": 2, "name": "s53b-control-minimal-end", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:29:41+00:00", "staged": "00002__wfv__s53b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53c", "pass": 1, "name": "s53c-control-minimal", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00007__wfv__s53c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53c", "pass": 2, "name": "s53c-control-minimal", "sha256": "c940ba0a774cf4d6d63b0c67260ab38054579c265ae8a8d005181cbffd79090f", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00007__wfv__s53c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53c", "pass": 1, "name": "fonttable-override-octet-upper", "sha256": "6a5fe4cb9971efdf2bd3fe193b1b4e155c275eedab2a407298ebd8971ce82eef", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00003__wfv__fonttable-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:24:23.385 'Word found unreadable content in 00003__wfv__fonttable-override-octet-upper.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:24:24.335 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__fonttable-override-octet-...)\""]}
{"run": "s53c", "pass": 2, "name": "fonttable-override-octet-upper", "sha256": "6a5fe4cb9971efdf2bd3fe193b1b4e155c275eedab2a407298ebd8971ce82eef", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00003__wfv__fonttable-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:31.640 \"Word found unreadable content in 00003__wfv__fonttable-override-octet-upper.docx. Do you want to re … ? If you trust the source of this document, click Yes.\"", "2026-10-26 09:30:31.640 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__fonttable-override-octet-...)\""]}
{"run": "s53c", "pass": 1, "name": "fonttable-override-octet-charset", "sha256": "72aae2c806d3aa78e7855d5cffd87181cbe35125bb035a1aa94e771a80e45ba6", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00002__wfv__fonttable-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:24:14.899 'Word found unreadable content in 00002__wfv__fonttable-override-octet-charset.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:24:15.735 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__fonttable-override-octet-...)\""]}
{"run": "s53c", "pass": 2, "name": "fonttable-override-octet-charset", "sha256": "72aae2c806d3aa78e7855d5cffd87181cbe35125bb035a1aa94e771a80e45ba6", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00002__wfv__fonttable-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:13.827 'Word found unreadable content in 00002__wfv__fonttable-override-octet-charset.docx. Do you want to  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s53c", "pass": 1, "name": "fonttable-override-image-png", "sha256": "2bca23dddba2ee04a8d350d310eaffa1b120ce3e8a59cf2e05d1264b959a5c6d", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00001__wfv__fonttable-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:24:05.885 'Word found unreadable content in 00001__wfv__fonttable-override-image-png.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:24:06.718 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__fonttable-override-image-...)\""]}
{"run": "s53c", "pass": 2, "name": "fonttable-override-image-png", "sha256": "2bca23dddba2ee04a8d350d310eaffa1b120ce3e8a59cf2e05d1264b959a5c6d", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00001__wfv__fonttable-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:59.816 'Word found unreadable content in 00001__wfv__fonttable-override-image-png.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:00.686 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__fonttable-override-image-...)\""]}
{"run": "s53c", "pass": 1, "name": "fonttable-override-foo-xml", "sha256": "0b3a6d1e58e37ca2d93e6ee6fc43e0636b3b48e8bb2d5904e3348f8dd3603363", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00000__wfv__fonttable-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:23:56.868 'Word found unreadable content in 00000__wfv__fonttable-override-foo-xml.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:23:57.780 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-foo-xm...)\""]}
{"run": "s53c", "pass": 2, "name": "fonttable-override-foo-xml", "sha256": "0b3a6d1e58e37ca2d93e6ee6fc43e0636b3b48e8bb2d5904e3348f8dd3603363", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00000__wfv__fonttable-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:29:51.379 'Word found unreadable content in 00000__wfv__fonttable-override-foo-xml.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:29:52.165 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__fonttable-override-foo-xm...)\""]}
{"run": "s53c", "pass": 1, "name": "numbering-override-octet-upper", "sha256": "31b408bd8cab0d9a75eb2149345df54a17fe83c9cbcb0ba3d1e2811e210024d3", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00005__wfv__numbering-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:24:47.299 'Word found unreadable content in 00005__wfv__numbering-override-octet-upper.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:24:48.120 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__numbering-override-octet-...)\""]}
{"run": "s53c", "pass": 2, "name": "numbering-override-octet-upper", "sha256": "31b408bd8cab0d9a75eb2149345df54a17fe83c9cbcb0ba3d1e2811e210024d3", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00005__wfv__numbering-override-octet-upper.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:40.079 'Word found unreadable content in 00005__wfv__numbering-override-octet-upper.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:40.864 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__numbering-override-octet-...)\""]}
{"run": "s53c", "pass": 1, "name": "numbering-override-octet-charset", "sha256": "e9a7a6ba6158d91fd20b8332f85ab7b5da2cfbe7d4d96ccba4ae12ff630de813", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00004__wfv__numbering-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:24:32.904 'Word found unreadable content in 00004__wfv__numbering-override-octet-charset.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:24:41.413 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__numbering-override-octet-...)\""]}
{"run": "s53c", "pass": 2, "name": "numbering-override-octet-charset", "sha256": "e9a7a6ba6158d91fd20b8332f85ab7b5da2cfbe7d4d96ccba4ae12ff630de813", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00004__wfv__numbering-override-octet-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:35.879 'Word found unreadable content in 00004__wfv__numbering-override-octet-charset.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:36.775 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__numbering-override-octet-...)\""]}
{"run": "s53c", "pass": 1, "name": "s53c-control-minimal-end", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:24:49+00:00", "staged": "00006__wfv__s53c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53c", "pass": 2, "name": "s53c-control-minimal-end", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:30:41+00:00", "staged": "00006__wfv__s53c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53d", "pass": 1, "name": "s53d-control-minimal", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00007__wfv__s53d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53d", "pass": 2, "name": "s53d-control-minimal", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00007__wfv__s53d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53d", "pass": 1, "name": "numbering-override-image-png", "sha256": "12dc7dd7f7cedc9ed986569e54c3142eb6d1300f465a124e6f3010812551b6ad", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00005__wfv__numbering-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:32.863 'Word found unreadable content in 00005__wfv__numbering-override-image-png.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:33.706 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__numbering-override-image-...)\""]}
{"run": "s53d", "pass": 2, "name": "numbering-override-image-png", "sha256": "12dc7dd7f7cedc9ed986569e54c3142eb6d1300f465a124e6f3010812551b6ad", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00005__wfv__numbering-override-image-png.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:11.780 'Word found unreadable content in 00005__wfv__numbering-override-image-png.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:12.613 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__numbering-override-image-...)\""]}
{"run": "s53d", "pass": 1, "name": "numbering-override-foo-xml", "sha256": "b752b67489a900494e1940dc776b62d2db6493b7474574be71e8fe3981693bb1", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00004__wfv__numbering-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:28.294 'Word found unreadable content in 00004__wfv__numbering-override-foo-xml.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:29.172 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__numbering-override-foo-xm...)\""]}
{"run": "s53d", "pass": 2, "name": "numbering-override-foo-xml", "sha256": "b752b67489a900494e1940dc776b62d2db6493b7474574be71e8fe3981693bb1", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00004__wfv__numbering-override-foo-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:07.562 'Word found unreadable content in 00004__wfv__numbering-override-foo-xml.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:08.332 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__numbering-override-foo-xm...)\""]}
{"run": "s53d", "pass": 1, "name": "numbering-override-empty", "sha256": "cc4ec9114d116472f792b5ec5190d9d85ebd0d89cf90465bf1336323d9f0d5f7", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00003__wfv__numbering-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:23.806 'Word found unreadable content in 00003__wfv__numbering-override-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:24.776 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-override-empty....)\""]}
{"run": "s53d", "pass": 2, "name": "numbering-override-empty", "sha256": "cc4ec9114d116472f792b5ec5190d9d85ebd0d89cf90465bf1336323d9f0d5f7", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00003__wfv__numbering-override-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:03.362 'Word found unreadable content in 00003__wfv__numbering-override-empty.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:04.147 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-override-empty....)\""]}
{"run": "s53d", "pass": 1, "name": "main-override-theme-type", "sha256": "ebefeb7701b17ebb24a5c35431191269089488039029ed61df1628a7fe0a35f9", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00002__wfv__main-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:18.884 'Word found unreadable content in 00002__wfv__main-override-theme-type.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:19.908 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-override-theme-type....)\""]}
{"run": "s53d", "pass": 2, "name": "main-override-theme-type", "sha256": "ebefeb7701b17ebb24a5c35431191269089488039029ed61df1628a7fe0a35f9", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00002__wfv__main-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:58.395 'Word found unreadable content in 00002__wfv__main-override-theme-type.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:59.198 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-override-theme-type....)\""]}
{"run": "s53d", "pass": 1, "name": "main-override-glossary-type", "sha256": "e920b88eef2486480bd1c37b57612b4e19aece71ad4ffa871f81b104bfa36dea", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00000__wfv__main-override-glossary-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:06.524 'Word found unreadable content in 00000__wfv__main-override-glossary-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s53d", "pass": 2, "name": "main-override-glossary-type", "sha256": "e920b88eef2486480bd1c37b57612b4e19aece71ad4ffa871f81b104bfa36dea", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00000__wfv__main-override-glossary-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:49.862 'Word found unreadable content in 00000__wfv__main-override-glossary-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:50.432 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__main-override-glossary-ty...)\""]}
{"run": "s53d", "pass": 1, "name": "main-override-header-type", "sha256": "d324da4b33f07bb6dd755dbfdace2386c31868f02de21e3567c1b306e8429333", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00001__wfv__main-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:12.488 \"Word found unreadable content in 00001__wfv__main-override-header-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.\"", "2026-10-26 09:25:12.488 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__main-override-header-type...)\""]}
{"run": "s53d", "pass": 2, "name": "main-override-header-type", "sha256": "d324da4b33f07bb6dd755dbfdace2386c31868f02de21e3567c1b306e8429333", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00001__wfv__main-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:30:54.195 'Word found unreadable content in 00001__wfv__main-override-header-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:30:55.000 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__main-override-header-type...)\""]}
{"run": "s53d", "pass": 1, "name": "s53d-control-minimal-end", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:25:34+00:00", "staged": "00006__wfv__s53d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53d", "pass": 2, "name": "s53d-control-minimal-end", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:31:13+00:00", "staged": "00006__wfv__s53d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53e", "pass": 1, "name": "s53e-control-minimal", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00007__wfv__s53e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53e", "pass": 2, "name": "s53e-control-minimal", "sha256": "78e76aaf80e6ac15e40cac9edf650f52649bd671c506e221dc1966777c6db020", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00007__wfv__s53e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53e", "pass": 1, "name": "main-override-footer-type", "sha256": "4811c413899302e14babc237dd7d46324564becd3659f3121ea8ba07a4b4feb7", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00003__wfv__main-override-footer-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:08.714 'Word found unreadable content in 00003__wfv__main-override-footer-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:09.591 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__main-override-footer-type...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-footer-type", "sha256": "4811c413899302e14babc237dd7d46324564becd3659f3121ea8ba07a4b4feb7", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00003__wfv__main-override-footer-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:49.805 'Word found unreadable content in 00003__wfv__main-override-footer-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:50.735 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__main-override-footer-type...)\""]}
{"run": "s53e", "pass": 1, "name": "main-override-footnotes-type", "sha256": "7499826e8dc67598d82f81413f1f247de8f0a175ab2a58628db15fa53ba4418b", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00004__wfv__main-override-footnotes-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:12.995 'Word found unreadable content in 00004__wfv__main-override-footnotes-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:13.798 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__main-override-footnotes-t...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-footnotes-type", "sha256": "7499826e8dc67598d82f81413f1f247de8f0a175ab2a58628db15fa53ba4418b", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00004__wfv__main-override-footnotes-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:58.102 'Word found unreadable content in 00004__wfv__main-override-footnotes-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:59.040 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__main-override-footnotes-t...)\""]}
{"run": "s53e", "pass": 1, "name": "main-override-endnotes-type", "sha256": "e0871228afc1668e081d001cd827d33c759025488a8782c0cee86be04c64b915", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00001__wfv__main-override-endnotes-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:59.032 'Word found unreadable content in 00001__wfv__main-override-endnotes-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:59.967 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__main-override-endnotes-ty...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-endnotes-type", "sha256": "e0871228afc1668e081d001cd827d33c759025488a8782c0cee86be04c64b915", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00001__wfv__main-override-endnotes-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:36.719 'Word found unreadable content in 00001__wfv__main-override-endnotes-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:37.604 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__main-override-endnotes-ty...)\""]}
{"run": "s53e", "pass": 1, "name": "main-override-comments-type", "sha256": "2fa2a70a1e893533c8a2c0bff602edd82fbe43d0d1d48d92e6fd906ee8e01bf1", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00000__wfv__main-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:25:54.698 'Word found unreadable content in 00000__wfv__main-override-comments-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:25:55.294 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__main-override-comments-ty...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-comments-type", "sha256": "2fa2a70a1e893533c8a2c0bff602edd82fbe43d0d1d48d92e6fd906ee8e01bf1", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00000__wfv__main-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:32.318 'Word found unreadable content in 00000__wfv__main-override-comments-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:33.179 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__main-override-comments-ty...)\""]}
{"run": "s53e", "pass": 1, "name": "main-override-settings-type", "sha256": "dcd93adbd0025cf6b26ce3df08e4df06e510e7afbf42712093259a544ac5222d", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00005__wfv__main-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:17.367 'Word found unreadable content in 00005__wfv__main-override-settings-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:18.347 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__main-override-settings-ty...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-settings-type", "sha256": "dcd93adbd0025cf6b26ce3df08e4df06e510e7afbf42712093259a544ac5222d", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00005__wfv__main-override-settings-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:07.115 'Word found unreadable content in 00005__wfv__main-override-settings-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:32:08.050 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__main-override-settings-ty...)\""]}
{"run": "s53e", "pass": 1, "name": "main-override-fonttable-type", "sha256": "541c386fdada46d5627d57a31b01304421e876eb5b894d1254e9b3b41255d8e2", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00002__wfv__main-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:04.395 'Word found unreadable content in 00002__wfv__main-override-fonttable-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:05.243 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-override-fonttable-t...)\""]}
{"run": "s53e", "pass": 2, "name": "main-override-fonttable-type", "sha256": "541c386fdada46d5627d57a31b01304421e876eb5b894d1254e9b3b41255d8e2", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00002__wfv__main-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:31:43.266 'Word found unreadable content in 00002__wfv__main-override-fonttable-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:31:44.166 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__main-override-fonttable-t...)\""]}
{"run": "s53e", "pass": 1, "name": "s53e-control-minimal-end", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:26:19+00:00", "staged": "00006__wfv__s53e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53e", "pass": 2, "name": "s53e-control-minimal-end", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:32:08+00:00", "staged": "00006__wfv__s53e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53f", "pass": 1, "name": "s53f-control-minimal", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00002__wfv__s53f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53f", "pass": 2, "name": "s53f-control-minimal", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00002__wfv__s53f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53f", "pass": 1, "name": "main-override-numbering-type", "sha256": "2dae93e99250fb43353ccb57737849b7680ae03489ef050c7cda71dd5217cde2", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00000__wfv__main-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:28.629 'Word found unreadable content in 00000__wfv__main-override-numbering-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:29.466 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__main-override-numbering-t...)\""]}
{"run": "s53f", "pass": 2, "name": "main-override-numbering-type", "sha256": "2dae93e99250fb43353ccb57737849b7680ae03489ef050c7cda71dd5217cde2", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00000__wfv__main-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:28.382 'Word found unreadable content in 00000__wfv__main-override-numbering-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'"]}
{"run": "s53f", "pass": 1, "name": "settings-override-main-type", "sha256": "df98b34b70226d9fd905f2a404249b3689c9b3ddcbd44e7fbcfb0bee9ed446dd", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00005__wfv__settings-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:41.703 'Word found unreadable content in 00005__wfv__settings-override-main-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:42.581 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__settings-override-main-ty...)\""]}
{"run": "s53f", "pass": 2, "name": "settings-override-main-type", "sha256": "df98b34b70226d9fd905f2a404249b3689c9b3ddcbd44e7fbcfb0bee9ed446dd", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00005__wfv__settings-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:46.197 'Word found unreadable content in 00005__wfv__settings-override-main-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:32:46.741 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__settings-override-main-ty...)\""]}
{"run": "s53f", "pass": 1, "name": "settings-override-numbering-type", "sha256": "d4036be15f4fc7c6cdfed53d082a51e3eafe9eb340250c4de3f419cb1ec8b819", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00006__wfv__settings-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:45.945 'Word found unreadable content in 00006__wfv__settings-override-numbering-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:46.805 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-numberi...)\""]}
{"run": "s53f", "pass": 2, "name": "settings-override-numbering-type", "sha256": "d4036be15f4fc7c6cdfed53d082a51e3eafe9eb340250c4de3f419cb1ec8b819", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00006__wfv__settings-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:50.666 'Word found unreadable content in 00006__wfv__settings-override-numbering-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:32:51.526 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-override-numberi...)\""]}
{"run": "s53f", "pass": 1, "name": "settings-override-header-type", "sha256": "79be997fffbbe9941142ea55895fc97af6a11785e14b4239292e3a12a3e026dd", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00004__wfv__settings-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:37.283 'Word found unreadable content in 00004__wfv__settings-override-header-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:38.313 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__settings-override-header-...)\""]}
{"run": "s53f", "pass": 2, "name": "settings-override-header-type", "sha256": "79be997fffbbe9941142ea55895fc97af6a11785e14b4239292e3a12a3e026dd", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00004__wfv__settings-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:41.880 'Word found unreadable content in 00004__wfv__settings-override-header-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:32:42.728 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__settings-override-header-...)\""]}
{"run": "s53f", "pass": 1, "name": "settings-override-fonttable-type", "sha256": "f5e9f34ea9425832dc9bb59dcf3902c7c7f00f7287912c69bf9993ccc8bc3480", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00003__wfv__settings-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:33.013 'Word found unreadable content in 00003__wfv__settings-override-fonttable-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:33.861 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-override-fonttab...)\""]}
{"run": "s53f", "pass": 2, "name": "settings-override-fonttable-type", "sha256": "f5e9f34ea9425832dc9bb59dcf3902c7c7f00f7287912c69bf9993ccc8bc3480", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00003__wfv__settings-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:37.681 \"Word found unreadable content in 00003__wfv__settings-override-fonttable-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.\"", "2026-10-26 09:32:37.682 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-override-fonttab...)\""]}
{"run": "s53f", "pass": 1, "name": "settings-override-theme-type", "sha256": "118618eee67d9e9b20cf71648680ebead95e2fd28a471b3792d574e19ea92abb", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00007__wfv__settings-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:26:50.195 'Word found unreadable content in 00007__wfv__settings-override-theme-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:26:51.054 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-theme-t...)\""]}
{"run": "s53f", "pass": 2, "name": "settings-override-theme-type", "sha256": "118618eee67d9e9b20cf71648680ebead95e2fd28a471b3792d574e19ea92abb", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00007__wfv__settings-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:32:54.930 'Word found unreadable content in 00007__wfv__settings-override-theme-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:32:55.717 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-override-theme-t...)\""]}
{"run": "s53f", "pass": 1, "name": "s53f-control-minimal-end", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:26:51+00:00", "staged": "00001__wfv__s53f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53f", "pass": 2, "name": "s53f-control-minimal-end", "sha256": "23b03320df4545d916a2492fb266b1e1757ce0bc2bbc90edd3b9279f06cf458a", "observedAt": "2026-10-26T13:32:55+00:00", "staged": "00001__wfv__s53f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53g", "pass": 1, "name": "s53g-control-minimal", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00005__wfv__s53g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53g", "pass": 2, "name": "s53g-control-minimal", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00005__wfv__s53g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53g", "pass": 1, "name": "numbering-override-main-type", "sha256": "7832b5bb17d01ed1b19e4637f0bfbd9983dd8451603043c38f04fc89c64786f4", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00002__wfv__numbering-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:08.828 'Word found unreadable content in 00002__wfv__numbering-override-main-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:09.668 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__numbering-override-main-t...)\""]}
{"run": "s53g", "pass": 2, "name": "numbering-override-main-type", "sha256": "7832b5bb17d01ed1b19e4637f0bfbd9983dd8451603043c38f04fc89c64786f4", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00002__wfv__numbering-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:12.514 'Word found unreadable content in 00002__wfv__numbering-override-main-type.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:13.332 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__numbering-override-main-t...)\""]}
{"run": "s53g", "pass": 1, "name": "numbering-override-styles-type", "sha256": "ba3fd57cde8be7331e7a801f7ac30c104ce55c8753e21c27b6d55f7bdc8092e3", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00003__wfv__numbering-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:13.045 'Word found unreadable content in 00003__wfv__numbering-override-styles-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:13.865 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-override-styles...)\""]}
{"run": "s53g", "pass": 2, "name": "numbering-override-styles-type", "sha256": "ba3fd57cde8be7331e7a801f7ac30c104ce55c8753e21c27b6d55f7bdc8092e3", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00003__wfv__numbering-override-styles-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:16.697 'Word found unreadable content in 00003__wfv__numbering-override-styles-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:17.539 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-override-styles...)\""]}
{"run": "s53g", "pass": 1, "name": "numbering-override-header-type", "sha256": "fb80d2781713f31f86e6bc8322854bf1e158ef9c11b362284d804d4bb9d4d018", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00001__wfv__numbering-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:04.563 'Word found unreadable content in 00001__wfv__numbering-override-header-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:05.435 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__numbering-override-header...)\""]}
{"run": "s53g", "pass": 2, "name": "numbering-override-header-type", "sha256": "fb80d2781713f31f86e6bc8322854bf1e158ef9c11b362284d804d4bb9d4d018", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00001__wfv__numbering-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:08.329 'Word found unreadable content in 00001__wfv__numbering-override-header-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:09.115 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__numbering-override-header...)\""]}
{"run": "s53g", "pass": 1, "name": "numbering-override-fonttable-type", "sha256": "94cea678ac00ff52f78425f74a40fa2badba53988e73d07f0f75e9736bca5f9c", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00000__wfv__numbering-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:00.032 'Word found unreadable content in 00000__wfv__numbering-override-fonttable-type.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:00.969 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__numbering-override-fontta...)\""]}
{"run": "s53g", "pass": 2, "name": "numbering-override-fonttable-type", "sha256": "94cea678ac00ff52f78425f74a40fa2badba53988e73d07f0f75e9736bca5f9c", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00000__wfv__numbering-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:04.130 'Word found unreadable content in 00000__wfv__numbering-override-fonttable-type.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:04.915 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__numbering-override-fontta...)\""]}
{"run": "s53g", "pass": 1, "name": "styles-override-main-type", "sha256": "bf1aa82ed7094c97c88f32b730c474a7089901291e79a78e32a6187b8d442082", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00006__wfv__styles-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:17.413 'Word found unreadable content in 00006__wfv__styles-override-main-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:18.249 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-override-main-type...)\""]}
{"run": "s53g", "pass": 2, "name": "styles-override-main-type", "sha256": "bf1aa82ed7094c97c88f32b730c474a7089901291e79a78e32a6187b8d442082", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00006__wfv__styles-override-main-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:21.045 'Word found unreadable content in 00006__wfv__styles-override-main-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:21.864 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-override-main-type...)\""]}
{"run": "s53g", "pass": 1, "name": "styles-override-numbering-type", "sha256": "0ffdb42bd74bb2bab3b57a6e42859bac9317ca3b673eab37e1500e9c977e6ccd", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00007__wfv__styles-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:21.662 'Word found unreadable content in 00007__wfv__styles-override-numbering-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:22.516 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-override-numbering...)\""]}
{"run": "s53g", "pass": 2, "name": "styles-override-numbering-type", "sha256": "0ffdb42bd74bb2bab3b57a6e42859bac9317ca3b673eab37e1500e9c977e6ccd", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00007__wfv__styles-override-numbering-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:25.262 'Word found unreadable content in 00007__wfv__styles-override-numbering-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:25.805 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-override-numbering...)\""]}
{"run": "s53g", "pass": 1, "name": "s53g-control-minimal-end", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:27:22+00:00", "staged": "00004__wfv__s53g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53g", "pass": 2, "name": "s53g-control-minimal-end", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:33:25+00:00", "staged": "00004__wfv__s53g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53h", "pass": 1, "name": "s53h-control-minimal", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00002__wfv__s53h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53h", "pass": 2, "name": "s53h-control-minimal", "sha256": "8ac6bfb91e63af67f2f12d6ddb9d224cd24b5b9ddf016fc3c32f298ad1bb1b05", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00002__wfv__s53h-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53h-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53h", "pass": 1, "name": "styles-override-header-type", "sha256": "3e2a3416cd854035bd73faed35965e01d8e4162dd66f9fd162e28b0c1a1a6c19", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00006__wfv__styles-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:00.713 'Word found unreadable content in 00006__wfv__styles-override-header-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:01.610 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-override-header-ty...)\""]}
{"run": "s53h", "pass": 2, "name": "styles-override-header-type", "sha256": "3e2a3416cd854035bd73faed35965e01d8e4162dd66f9fd162e28b0c1a1a6c19", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00006__wfv__styles-override-header-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:49.445 'Word found unreadable content in 00006__wfv__styles-override-header-type.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:50.259 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-override-header-ty...)\""]}
{"run": "s53h", "pass": 1, "name": "styles-override-fonttable-type", "sha256": "a0659f53f20041196cd46d0fb554792b73a57f312e61abc1b8a80bce52e5866a", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00005__wfv__styles-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:48.066 'Word found unreadable content in 00005__wfv__styles-override-fonttable-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:53.597 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-override-fonttable...)\""]}
{"run": "s53h", "pass": 2, "name": "styles-override-fonttable-type", "sha256": "a0659f53f20041196cd46d0fb554792b73a57f312e61abc1b8a80bce52e5866a", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00005__wfv__styles-override-fonttable-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:45.279 'Word found unreadable content in 00005__wfv__styles-override-fonttable-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:46.065 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-override-fonttable...)\""]}
{"run": "s53h", "pass": 1, "name": "styles-override-theme-type", "sha256": "b9780a86f257f1763bf72d6b93e23e8a4b7f22900c4f85eb99ced88898241313", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00007__wfv__styles-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:28:06.684 'Word found unreadable content in 00007__wfv__styles-override-theme-type.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:28:07.319 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-override-theme-typ...)\""]}
{"run": "s53h", "pass": 2, "name": "styles-override-theme-type", "sha256": "b9780a86f257f1763bf72d6b93e23e8a4b7f22900c4f85eb99ced88898241313", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00007__wfv__styles-override-theme-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:53.628 'Word found unreadable content in 00007__wfv__styles-override-theme-type.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:54.413 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-override-theme-typ...)\""]}
{"run": "s53h", "pass": 1, "name": "styles-override-comments-type", "sha256": "0075019d042984a3b3fe4a548448eeebf08ee106448a9e4489c7ec39c0743b98", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00004__wfv__styles-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:43.318 'Word found unreadable content in 00004__wfv__styles-override-comments-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:44.008 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-override-comments-...)\""]}
{"run": "s53h", "pass": 2, "name": "styles-override-comments-type", "sha256": "0075019d042984a3b3fe4a548448eeebf08ee106448a9e4489c7ec39c0743b98", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00004__wfv__styles-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:41.112 'Word found unreadable content in 00004__wfv__styles-override-comments-type.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:41.897 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-override-comments-...)\""]}
{"run": "s53h", "pass": 1, "name": "settings-override-comments-type", "sha256": "a6b36c64a0c32435e9b61de5209077f4bcb638723b9b51e9ef9635cf5db48673", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00003__wfv__settings-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:38.529 'Word found unreadable content in 00003__wfv__settings-override-comments-type.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:39.386 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-override-comment...)\""]}
{"run": "s53h", "pass": 2, "name": "settings-override-comments-type", "sha256": "a6b36c64a0c32435e9b61de5209077f4bcb638723b9b51e9ef9635cf5db48673", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00003__wfv__settings-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:36.880 'Word found unreadable content in 00003__wfv__settings-override-comments-type.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:37.463 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__settings-override-comment...)\""]}
{"run": "s53h", "pass": 1, "name": "numbering-override-comments-type", "sha256": "aff30486f65c81c6895bd554ddd7f621aa0222413ff1c581c1cfec660cf0571f", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00000__wfv__numbering-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:27:33.745 'Word found unreadable content in 00000__wfv__numbering-override-comments-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:27:34.570 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__numbering-override-commen...)\""]}
{"run": "s53h", "pass": 2, "name": "numbering-override-comments-type", "sha256": "aff30486f65c81c6895bd554ddd7f621aa0222413ff1c581c1cfec660cf0571f", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00000__wfv__numbering-override-comments-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:33:32.513 'Word found unreadable content in 00000__wfv__numbering-override-comments-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:33:33.315 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__numbering-override-commen...)\""]}
{"run": "s53h", "pass": 1, "name": "s53h-control-minimal-end", "sha256": "54ee4a813779f3b62e2f21b1f8acc4e8847cf27d76d8a27d102a4afa14e0d8c0", "observedAt": "2026-10-26T13:28:07+00:00", "staged": "00001__wfv__s53h-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53h-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s53h", "pass": 2, "name": "s53h-control-minimal-end", "sha256": "54ee4a813779f3b62e2f21b1f8acc4e8847cf27d76d8a27d102a4afa14e0d8c0", "observedAt": "2026-10-26T13:33:54+00:00", "staged": "00001__wfv__s53h-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s53h-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 53 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s53builder.mts`:

```ts
// Session 53 (2026-10-26): the shapes the review of layers 156-160 says the content-type layers judge without evidence.
// - s53a/s53b (#739): a second relationship to an eagerly read part. A footer relationship the body references, to the
//   main document, the related numbering part or the styles part, each typed with another Word type (session 50's and
//   49's refused shapes), with a calibration typed correctly; and the styles part also the target of the main
//   document's settings relationship, typed with the settings type (and its calibration typed styles).
// - s53b-s53h (#740): shapes the recovery sentence cites a session for but Word was never shown. Settings, fontTable and
//   numbering typed with the four other s49a/s50c spellings (session 50 showed `application/octet-stream` only); the
//   main document typed with each other mapped Word type (session 50 showed the styles type only); settings,
//   numbering and styles typed with other mapped types (sessions 49/50 showed one pair each); an empty numbering
//   ContentType (layer 157 covers styles, settings and fontTable only).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s53a pnpm exec tsx s53builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN_TYPE = `${WML}.document.main+xml`;
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

type Kind = "numbering" | "settings" | "fontTable";
/** The relationship segment, the part body and the content type of each kind (the bodies session 47 used). */
const KINDS: Record<Kind, { root: string; ct: string }> = {
    numbering: { root: `${XML_DECL}<w:numbering xmlns:w="${W}"/>`, ct: `${WML}.numbering+xml` },
    settings: { root: `${XML_DECL}<w:settings xmlns:w="${W}"/>`, ct: `${WML}.settings+xml` },
    fontTable: { root: `${XML_DECL}<w:fonts xmlns:w="${W}"/>`, ct: `${WML}.fontTable+xml` },
};
/** The other mapped Word content types the rows type a part with. */
const TYPES = {
    main: MAIN_TYPE,
    styles: STYLES_TYPE,
    theme: "application/vnd.openxmlformats-officedocument.theme+xml",
    glossary: `${WML}.document.glossary+xml`,
    header: `${WML}.header+xml`,
    footer: `${WML}.footer+xml`,
    footnotes: `${WML}.footnotes+xml`,
    endnotes: `${WML}.endnotes+xml`,
    comments: `${WML}.comments+xml`,
    settings: KINDS.settings.ct,
    fontTable: KINDS.fontTable.ct,
    numbering: KINDS.numbering.ct,
};
const SPELLINGS: Array<[string, string]> = [
    ["octet-upper", "APPLICATION/OCTET-STREAM"],
    ["octet-charset", "application/octet-stream; charset=utf-8"],
    ["image-png", "image/png"],
    ["foo-xml", "application/foo+xml"],
];

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${REL}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const retype = (ct: string, part: string, own: string, type: string) =>
    replaceOnce(ct, `<Override PartName="/${part}" ContentType="${own}"/>`, `<Override PartName="/${part}" ContentType="${type}"/>`);
const control = () => buildDocx({ ...P });

/** The minimal package plus `word/<kind>.xml` related from the main document's sidecar as rId2, typed `type`. */
const withRelated = (kind: Kind, type = KINDS[kind].ct): Record<string, string> => ({
    ...P,
    [`word/${kind}.xml`]: KINDS[kind].root,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", kind, `${kind}.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}.xml`, type]),
});
const relatedTyped = (kind: Kind, type: string) => buildDocx(withRelated(kind, type));
const mainTyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, "word/document.xml", MAIN_TYPE, type) });
const stylesTyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) });

/** `parts` plus a footer relationship (rIdF) to `target` (relative to word/) that the body's section references. */
const withReadFooter = (parts: Record<string, string>, target: string): Record<string, string> => ({
    ...parts,
    "word/document.xml": replaceOnce(
        replaceOnce(parts["word/document.xml"]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
        "<w:sectPr>",
        `<w:sectPr><w:footerReference w:type="default" r:id="rIdF"/>`,
    ),
    [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", target)),
});
const mainFooterCoReach = (type: string) =>
    buildDocx(withReadFooter({ ...P, [CT]: retype(P[CT]!, "word/document.xml", MAIN_TYPE, type) }, "document.xml"));
const numberingFooterCoReach = (type: string) => buildDocx(withReadFooter(withRelated("numbering", type), "numbering.xml"));
const stylesFooterCoReach = (type: string) =>
    buildDocx(withReadFooter({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) }, "styles.xml"));
/** The styles part also the target of the main document's settings relationship (review S5), typed `type`. */
const stylesSettingsCoReach = (type: string) =>
    buildDocx({
        ...P,
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", "settings", "styles.xml")),
        [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type),
    });

type Row = [string, string, () => Promise<Uint8Array>];
const spellingRows = (kind: Kind): Row[] =>
    SPELLINGS.map(([slug, type]) => [
        `${kind.toLowerCase()}-override-${slug}`,
        `#740: a related word/${kind}.xml typed ${type}`,
        () => relatedTyped(kind, type),
    ]);
const mainRow = (name: keyof typeof TYPES): Row => [
    `main-override-${name.toLowerCase()}-type`,
    `#740: main document Override typed with the ${name} content type`,
    () => mainTyped(TYPES[name]),
];
const relatedRow = (kind: Kind, name: keyof typeof TYPES): Row => [
    `${kind.toLowerCase()}-override-${name.toLowerCase()}-type`,
    `#740: a related word/${kind}.xml typed with the ${name} content type`,
    () => relatedTyped(kind, TYPES[name]),
];
const stylesRow = (name: keyof typeof TYPES): Row => [
    `styles-override-${name.toLowerCase()}-type`,
    `#740: word/styles.xml typed with the ${name} content type`,
    () => stylesTyped(TYPES[name]),
];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const [fontTableSpellings, numberingSpellings, settingsSpellings] = [
    spellingRows("fontTable"),
    spellingRows("numbering"),
    spellingRows("settings"),
];

const chunks: Record<string, Row[]> = {
    s53a: withControls("s53a", [
        [
            "coreach-footer-main-calibration",
            "#739 calibration: a footer relationship the body references targets word/document.xml, typed main",
            () => mainFooterCoReach(MAIN_TYPE),
        ],
        [
            "coreach-footer-main-styles-type",
            "#739: the same, the main document typed with the styles content type",
            () => mainFooterCoReach(STYLES_TYPE),
        ],
        [
            "coreach-footer-numbering-calibration",
            "#739 calibration: a footer relationship the body references targets the related word/numbering.xml, typed numbering",
            () => numberingFooterCoReach(KINDS.numbering.ct),
        ],
        [
            "coreach-footer-numbering-settings-type",
            "#739: the same, numbering typed with the settings content type",
            () => numberingFooterCoReach(KINDS.settings.ct),
        ],
        [
            "coreach-footer-styles-calibration",
            "#739 calibration: a footer relationship the body references targets word/styles.xml, typed styles",
            () => stylesFooterCoReach(STYLES_TYPE),
        ],
        [
            "coreach-footer-styles-settings-type",
            "#739: the same, styles typed with the settings content type",
            () => stylesFooterCoReach(KINDS.settings.ct),
        ],
    ]),
    s53b: withControls("s53b", [
        [
            "coreach-settings-styles-calibration",
            "#739 calibration: word/styles.xml is also the target of the main document's settings relationship, typed styles",
            () => stylesSettingsCoReach(STYLES_TYPE),
        ],
        [
            "coreach-settings-styles-settings-type",
            "#739 (review S5): the same, styles typed with the settings content type",
            () => stylesSettingsCoReach(KINDS.settings.ct),
        ],
        ...settingsSpellings,
    ]),
    s53c: withControls("s53c", [...fontTableSpellings, ...numberingSpellings.slice(0, 2)]),
    s53d: withControls("s53d", [
        ...numberingSpellings.slice(2),
        [
            "numbering-override-empty",
            '#740: a related word/numbering.xml whose Override has ContentType=""',
            () => relatedTyped("numbering", ""),
        ],
        mainRow("theme"),
        mainRow("glossary"),
        mainRow("header"),
    ]),
    s53e: withControls("s53e", [
        mainRow("footer"),
        mainRow("footnotes"),
        mainRow("endnotes"),
        mainRow("comments"),
        mainRow("settings"),
        mainRow("fontTable"),
    ]),
    s53f: withControls("s53f", [
        mainRow("numbering"),
        relatedRow("settings", "main"),
        relatedRow("settings", "numbering"),
        relatedRow("settings", "header"),
        relatedRow("settings", "fontTable"),
        relatedRow("settings", "theme"),
    ]),
    s53g: withControls("s53g", [
        relatedRow("numbering", "main"),
        relatedRow("numbering", "styles"),
        relatedRow("numbering", "header"),
        relatedRow("numbering", "fontTable"),
        stylesRow("main"),
        stylesRow("numbering"),
    ]),
    s53h: withControls("s53h", [
        stylesRow("header"),
        stylesRow("fontTable"),
        stylesRow("theme"),
        stylesRow("comments"),
        relatedRow("settings", "comments"),
        relatedRow("numbering", "comments"),
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-53 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s53a", "s53b", "s53c", "s53d", "s53e", "s53f", "s53g", "s53h")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s53/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-53 parts of docs/plans/evidence/word-probes-2026-10-24.md into s53/section.md.

Reads the chunk's specimens.jsonl (validator columns at 0b26c414, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s53/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s53a", "s53b", "s53c", "s53d", "s53e", "s53f", "s53g", "s53h")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s53/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 53: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 0b26c414",
    "",
    "The content-type shapes the review of layers 156–160 says those layers judge, or explain with a session, that no earlier session "
    "showed Word ([#739](https://github.com/jandira-tech/docx-validate/issues/739): a second relationship to an eagerly read part; "
    "[#740](https://github.com/jandira-tech/docx-validate/issues/740): the spellings and types the recovery sentence cites a session for). "
    "Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word "
    "log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings "
    "agree, and `unknown` otherwise; all 64 rows agree. The two times in Observed are the ends of the first and second runs. Shape is "
    "the builder's description of the specimen. The part bodies are session 47's empty roots.",
    "",
    "- A footer relationship the body references (`w:footerReference`) whose target is the main document, the related numbering part "
    "or the styles part gets the recovery offer, typed with its own type (the calibrations) and typed with session 49's and 50's refused "
    "types alike. So does `word/styles.xml` when the main document's settings relationship also targets it, typed styles or typed "
    "settings. Word-valid accepts all eight: false negatives, and the review's shapes are refused whatever the Override says.",
    "- `word/settings.xml`, `word/fontTable.xml` and `word/numbering.xml`, related by the main document, get the recovery offer typed "
    "`APPLICATION/OCTET-STREAM`, `application/octet-stream; charset=utf-8`, `image/png` or `application/foo+xml` (session 50 showed "
    "`application/octet-stream` only). Word-valid rejects all twelve.",
    "- The main document gets the recovery offer typed with the theme, glossary, header, footer, footnotes, endnotes, comments, "
    "settings, fontTable or numbering content type (session 50 showed the styles type only); word-valid rejects all ten.",
    "- A related settings part typed with the main document, numbering, header, fontTable, theme or comments type, a related numbering "
    "part typed with the main document, styles, header, fontTable or comments type, and the styles part typed with the main document, "
    "numbering, header, fontTable, theme or comments type all get the recovery offer; word-valid rejects all sixteen.",
    "- A related numbering part whose Override has `ContentType=\"\"` gets the recovery offer, as styles (session 49) and settings and "
    "fontTable (session 50) did. Word-valid accepts it: a false negative.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 0b26c414 | strict at 0b26c414 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 53</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 53 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s53builder.mts", ROOT / "s53builder.mts", "ts"), ("compare.py", ROOT / "s53/compare.py", "python"),
                         ("section.py", ROOT / "s53/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s53/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 54: 13:38Z–13:40Z on 2026-10-26, validator columns at 0b26c414

The shapes three follow-ups need before they land: the broken relationship targets whose `rels-broken` verdict [#734](https://github.com/jandira-tech/docx-validate/issues/734) moves from the Target's spelling to the part it resolves to; the attached-toolbar spellings and the empty id of [#743](https://github.com/jandira-tech/docx-validate/issues/743) (the review of layers 151–155, findings 2, 3 and S1); and the four duplicate cells session 50 did not show ([#744](https://github.com/jandira-tech/docx-validate/issues/744), finding 4). Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 27 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A `customXml` relationship from the main document's relationships part to an absent package-root `customXml/item1.xml` gets the recovery offer however the Target spells it: `../customXml/item1.xml` (vectors.docx's shape, the calibration), `/customXml/item1.xml`, `..\customXml\item1.xml`, `../CUSTOMXML/%69tem1.xml`, and `../../customXml/item1.xml`, whose extra `..` stays at the package root as RFC 3986 removes dot segments. Word-valid at 0b26c414 rejects only the calibration and the last: three false negatives.
- An image relationship to an absent `media/_rels/x.png`, `notes.rels` or `word/../customXml/x.png` opens clean, as the broken `media/image9.png` calibration does, and so does a reached glossary's `customXml` relationship to an absent `../customXml/item1.xml` (which resolves to `word/customXml/item1.xml`). Word-valid at 0b26c414 rejects all four by their spelling: false positives.
- The Word-clean toolbar fixture (`tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx`, re-zipped) opens clean unchanged, with its relationships part stored as `word/_rels/customizations.xml.RELS`, and with `wne:toolbarData r:id=""`. Word-valid rejects the `.RELS` spelling through `word-attached-toolbar-relationship`: a false positive. The Word-refused fixture (`tests/fixtures/broken/package.word-attached-toolbar-utf8.docx`) gets the recovery offer unchanged and with `word/customizations.xml` and its relationships part stored with `.XML` spellings; word-valid passes the `.XML` spelling: a false negative.
- Two fontTable or two webSettings relationships in `_rels/.rels`, beside the main document's own, open clean; two webSettings or two theme relationships in a reached glossary's relationships part get the recovery offer. Word-valid agrees on all four.

| Run    | Observed             | Specimen                           | Shape                                                                                                                                  | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 0b26c414                              | strict at 0b26c414                                                                                                                                                                                                             |
| ------ | -------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `s54a` | 13:38:47Z, 13:40:13Z | `s54a-control-minimal`             | control                                                                                                                                | `d1a934c730b0dda3` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54a` | 13:38:47Z, 13:40:13Z | `broken-customxml-calibration`     | #734 calibration (vectors.docx's shape): a customXml relationship from the main document's sidecar to an absent ../customXml/item1.xml | `f4c1d95fae3a596a` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken`                              | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54a` | 13:38:47Z, 13:40:13Z | `broken-customxml-absolute`        | #734: the same target spelled /customXml/item1.xml                                                                                     | `790a9a9d7cbd80c3` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54a` | 13:38:47Z, 13:40:13Z | `broken-customxml-backslash`       | #734: the same target spelled ..\customXml\item1.xml                                                                                   | `fc1a774fc7fdeac1` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54a` | 13:38:47Z, 13:40:13Z | `broken-customxml-escaped`         | #734: the same target spelled ../CUSTOMXML/%69tem1.xml                                                                                 | `12bc3dda52e6f86e` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54a` | 13:38:47Z, 13:40:13Z | `broken-customxml-above-root`      | #734: the same target spelled ../../customXml/item1.xml (above the package root)                                                       | `184d9b8088916065` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken`                              | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54a` | 13:38:47Z, 13:40:13Z | `s54a-control-minimal-end`         | control                                                                                                                                | `d1a934c730b0dda3` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54b` | 13:38:52Z, 13:40:19Z | `s54b-control-minimal`             | control                                                                                                                                | `d1a934c730b0dda3` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54b` | 13:38:52Z, 13:40:19Z | `broken-media-calibration`         | #734 calibration (tolerated): an image relationship from the main document's sidecar to an absent media/image9.png                     | `d13d0c6be5ccc5d5` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54b` | 13:38:52Z, 13:40:19Z | `broken-image-media-rels-folder`   | #734: an image relationship to an absent media/_rels/x.png                                                                             | `3a830099e1e92092` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken`                              | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54b` | 13:38:52Z, 13:40:19Z | `broken-image-notes-rels`          | #734: an image relationship to an absent notes.rels                                                                                    | `c33990490c00235c` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken`                              | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54b` | 13:38:52Z, 13:40:19Z | `broken-image-word-customxml`      | #734: an image relationship to an absent word/../customXml/x.png (resolves to word/customXml/x.png)                                    | `3fa4f4b9150662e3` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken`                              | invalid: `rels-broken`, `rels-target-missing`                                                                                                                                                                                  |
| `s54b` | 13:38:52Z, 13:40:19Z | `broken-customxml-from-glossary`   | #734: a reached glossary's customXml relationship to an absent ../customXml/item1.xml (resolves under word/)                           | `2fdc5f30f375b2fe` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken`                              | invalid: `rels-broken`, `paraid-missing-element`, `rels-target-missing`                                                                                                                                                        |
| `s54b` | 13:38:52Z, 13:40:19Z | `s54b-control-minimal-end`         | control                                                                                                                                | `d1a934c730b0dda3` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54c` | 13:39:09Z, 13:40:35Z | `s54c-control-minimal`             | control                                                                                                                                | `e9022a75397b8b4e` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54c` | 13:39:09Z, 13:40:35Z | `toolbar-clean-calibration`        | #743 calibration: the Word-clean toolbar fixture re-zipped unchanged                                                                   | `1bd77d059f5b58a4` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                                       |
| `s54c` | 13:39:09Z, 13:40:35Z | `toolbar-clean-sidecar-upper-rels` | #743: the same with its sidecar stored as word/_rels/customizations.xml.RELS                                                           | `1d5af69a695c4ca4` | clean-open     | clean-open     | clean-open                 | invalid: `word-attached-toolbar-relationship`       | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `word-attached-toolbar-relationship`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s54c` | 13:39:09Z, 13:40:35Z | `toolbar-clean-empty-id`           | #743: the same with wne:toolbarData r:id=""                                                                                            | `49deb16d41f543f6` | clean-open     | clean-open     | clean-open                 | valid                                               | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                                       |
| `s54c` | 13:39:09Z, 13:40:35Z | `toolbar-broken-calibration`       | #743 calibration: the Word-refused toolbar fixture re-zipped unchanged                                                                 | `f5f61abe9857e547` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-attached-toolbar-utf8`               | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `word-attached-toolbar-utf8`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`         |
| `s54c` | 13:39:09Z, 13:40:35Z | `toolbar-broken-upper-xml`         | #743: the same with word/customizations.xml and its sidecar stored with .XML spellings                                                 | `cfeb78d2c8ceb546` | repair-warning | repair-warning | unreadable-content-warning | valid                                               | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                                       |
| `s54c` | 13:39:09Z, 13:40:35Z | `s54c-control-minimal-end`         | control                                                                                                                                | `e9022a75397b8b4e` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54d` | 13:39:23Z, 13:40:50Z | `s54d-control-minimal`             | control                                                                                                                                | `e9022a75397b8b4e` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54d` | 13:39:23Z, 13:40:50Z | `dup-fonttable-package-rels`       | #744: the main document's fontTable relationship, and two more fontTable relationships in _rels/.rels                                  | `2c9929f882aaca63` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54d` | 13:39:23Z, 13:40:50Z | `dup-websettings-package-rels`     | #744: the main document's webSettings relationship, and two more webSettings relationships in _rels/.rels                              | `bd8b65c79c3a5083` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |
| `s54d` | 13:39:23Z, 13:40:50Z | `dup-websettings-glossary-sidecar` | #744: a reached glossary's sidecar holds two webSettings relationships to two parts                                                    | `017b32dfe1f02cd6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-web-settings-relationship` | invalid: `paraid-missing-element`, `word-duplicate-web-settings-relationship`                                                                                                                                                  |
| `s54d` | 13:39:23Z, 13:40:50Z | `dup-theme-glossary-sidecar`       | #744: a reached glossary's sidecar holds two theme relationships to two parts                                                          | `e214957b33d64daf` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-duplicate-theme-relationship`        | invalid: `paraid-missing-element`, `word-duplicate-theme-relationship`                                                                                                                                                         |
| `s54d` | 13:39:23Z, 13:40:50Z | `s54d-control-minimal-end`         | control                                                                                                                                | `e9022a75397b8b4e` | clean-open     | clean-open     | clean-open                 | valid                                               | valid                                                                                                                                                                                                                          |

<details><summary>Raw records, session 54</summary>

```jsonl
{"run": "s54a", "pass": 1, "name": "s54a-control-minimal", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00006__wfv__s54a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54a", "pass": 2, "name": "s54a-control-minimal", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00006__wfv__s54a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54a", "pass": 1, "name": "broken-customxml-calibration", "sha256": "f4c1d95fae3a596a23e5a3cb03f4792f037734f0c739d1c007d3c87e66a6e9d8", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00003__wfv__broken-customxml-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:38:41.898 'Word found unreadable content in 00003__wfv__broken-customxml-calibration.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:38:42.704 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__broken-customxml-calibrat...)\""]}
{"run": "s54a", "pass": 2, "name": "broken-customxml-calibration", "sha256": "f4c1d95fae3a596a23e5a3cb03f4792f037734f0c739d1c007d3c87e66a6e9d8", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00003__wfv__broken-customxml-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:07.581 'Word found unreadable content in 00003__wfv__broken-customxml-calibration.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:08.385 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__broken-customxml-calibrat...)\""]}
{"run": "s54a", "pass": 1, "name": "broken-customxml-absolute", "sha256": "790a9a9d7cbd80c3a86f75ba98ebd6eba8b101d68ecfa387fca0a46108be1335", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00001__wfv__broken-customxml-absolute.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:38:33.531 'Word found unreadable content in 00001__wfv__broken-customxml-absolute.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:38:34.325 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__broken-customxml-absolute...)\""]}
{"run": "s54a", "pass": 2, "name": "broken-customxml-absolute", "sha256": "790a9a9d7cbd80c3a86f75ba98ebd6eba8b101d68ecfa387fca0a46108be1335", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00001__wfv__broken-customxml-absolute.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:59.264 'Word found unreadable content in 00001__wfv__broken-customxml-absolute.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:00.072 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__broken-customxml-absolute...)\""]}
{"run": "s54a", "pass": 1, "name": "broken-customxml-backslash", "sha256": "fc1a774fc7fdeac107804d56730968a8fa83dd31c78db1b0cb23045df3ec24b3", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00002__wfv__broken-customxml-backslash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:38:37.714 'Word found unreadable content in 00002__wfv__broken-customxml-backslash.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:38:38.516 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__broken-customxml-backslas...)\""]}
{"run": "s54a", "pass": 2, "name": "broken-customxml-backslash", "sha256": "fc1a774fc7fdeac107804d56730968a8fa83dd31c78db1b0cb23045df3ec24b3", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00002__wfv__broken-customxml-backslash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:03.431 'Word found unreadable content in 00002__wfv__broken-customxml-backslash.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:04.184 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__broken-customxml-backslas...)\""]}
{"run": "s54a", "pass": 1, "name": "broken-customxml-escaped", "sha256": "12bc3dda52e6f86e0abe2eb6b7a8c8a1b056fd79ff7694909a7a2d4e8809aaf2", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00004__wfv__broken-customxml-escaped.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:38:46.064 'Word found unreadable content in 00004__wfv__broken-customxml-escaped.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:38:46.831 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__broken-customxml-escaped....)\""]}
{"run": "s54a", "pass": 2, "name": "broken-customxml-escaped", "sha256": "12bc3dda52e6f86e0abe2eb6b7a8c8a1b056fd79ff7694909a7a2d4e8809aaf2", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00004__wfv__broken-customxml-escaped.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:11.798 'Word found unreadable content in 00004__wfv__broken-customxml-escaped.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:12.591 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__broken-customxml-escaped....)\""]}
{"run": "s54a", "pass": 1, "name": "broken-customxml-above-root", "sha256": "184d9b8088916065426771c56bd8f70514b193e31b40601ee824f2d78a289725", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00000__wfv__broken-customxml-above-root.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:38:29.364 'Word found unreadable content in 00000__wfv__broken-customxml-above-root.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:38:30.151 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__broken-customxml-above-ro...)\""]}
{"run": "s54a", "pass": 2, "name": "broken-customxml-above-root", "sha256": "184d9b8088916065426771c56bd8f70514b193e31b40601ee824f2d78a289725", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00000__wfv__broken-customxml-above-root.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:55.031 'Word found unreadable content in 00000__wfv__broken-customxml-above-root.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:39:55.839 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__broken-customxml-above-ro...)\""]}
{"run": "s54a", "pass": 1, "name": "s54a-control-minimal-end", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:38:47+00:00", "staged": "00005__wfv__s54a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54a", "pass": 2, "name": "s54a-control-minimal-end", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:40:13+00:00", "staged": "00005__wfv__s54a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "s54b-control-minimal", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00006__wfv__s54b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "s54b-control-minimal", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00006__wfv__s54b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "broken-media-calibration", "sha256": "d13d0c6be5ccc5d554db972f26fec202783eec41a46d9bf5d694d9dfc94b1dc5", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00004__wfv__broken-media-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-media-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "broken-media-calibration", "sha256": "d13d0c6be5ccc5d554db972f26fec202783eec41a46d9bf5d694d9dfc94b1dc5", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00004__wfv__broken-media-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-media-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "broken-image-media-rels-folder", "sha256": "3a830099e1e92092315cef350db0e6e440c9cdb56b190f6bcc9ecc75c9363b2e", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00001__wfv__broken-image-media-rels-folder.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-media-rels-folder_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "broken-image-media-rels-folder", "sha256": "3a830099e1e92092315cef350db0e6e440c9cdb56b190f6bcc9ecc75c9363b2e", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00001__wfv__broken-image-media-rels-folder.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-media-rels-folder_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "broken-image-notes-rels", "sha256": "c33990490c00235c1b523ee98c6bd86bda65d5b655dffe3026bcabd35f6e0c62", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00002__wfv__broken-image-notes-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-notes-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "broken-image-notes-rels", "sha256": "c33990490c00235c1b523ee98c6bd86bda65d5b655dffe3026bcabd35f6e0c62", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00002__wfv__broken-image-notes-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-notes-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "broken-image-word-customxml", "sha256": "3fa4f4b9150662e3dbe83298f7422bf32235a5d21222a8731c9729898d2545af", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00003__wfv__broken-image-word-customxml.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-word-customxml_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "broken-image-word-customxml", "sha256": "3fa4f4b9150662e3dbe83298f7422bf32235a5d21222a8731c9729898d2545af", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00003__wfv__broken-image-word-customxml.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-image-word-customxml_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "broken-customxml-from-glossary", "sha256": "2fdc5f30f375b2fe4caf27dd48a08d44797b7ffa4030e4e69ba3c39df2dbf597", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00000__wfv__broken-customxml-from-glossary.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-customxml-from-glossary_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "broken-customxml-from-glossary", "sha256": "2fdc5f30f375b2fe4caf27dd48a08d44797b7ffa4030e4e69ba3c39df2dbf597", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00000__wfv__broken-customxml-from-glossary.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-customxml-from-glossary_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 1, "name": "s54b-control-minimal-end", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:38:52+00:00", "staged": "00005__wfv__s54b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54b", "pass": 2, "name": "s54b-control-minimal-end", "sha256": "d1a934c730b0dda3b0332a84243f7e6a6c7c339ad1c6dd1203889ebc31a88892", "observedAt": "2026-10-26T13:40:19+00:00", "staged": "00005__wfv__s54b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 1, "name": "s54c-control-minimal", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00001__wfv__s54c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 2, "name": "s54c-control-minimal", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00001__wfv__s54c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 1, "name": "toolbar-clean-calibration", "sha256": "1bd77d059f5b58a49b56af7ffc514fbfbea4fbd52713793e50fd4f158ae900bb", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00004__wfv__toolbar-clean-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 2, "name": "toolbar-clean-calibration", "sha256": "1bd77d059f5b58a49b56af7ffc514fbfbea4fbd52713793e50fd4f158ae900bb", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00004__wfv__toolbar-clean-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 1, "name": "toolbar-clean-sidecar-upper-rels", "sha256": "1d5af69a695c4ca4f772391453f8fe5034044a82bc970201bdff7ce4b05c9c73", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00006__wfv__toolbar-clean-sidecar-upper-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-sidecar-upper-rels_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 2, "name": "toolbar-clean-sidecar-upper-rels", "sha256": "1d5af69a695c4ca4f772391453f8fe5034044a82bc970201bdff7ce4b05c9c73", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00006__wfv__toolbar-clean-sidecar-upper-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-sidecar-upper-rels_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 1, "name": "toolbar-clean-empty-id", "sha256": "49deb16d41f543f62d699d6048077e6dd948efb8b2e27ae35fe07d865810e199", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00005__wfv__toolbar-clean-empty-id.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-empty-id_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 2, "name": "toolbar-clean-empty-id", "sha256": "49deb16d41f543f62d699d6048077e6dd948efb8b2e27ae35fe07d865810e199", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00005__wfv__toolbar-clean-empty-id.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF toolbar-clean-empty-id_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 1, "name": "toolbar-broken-calibration", "sha256": "f5f61abe9857e5473452ba35d0a941c4ded9461361e8be9beeb70d6a329e5a80", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00002__wfv__toolbar-broken-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:02.282 'Word found unreadable content in 00002__wfv__toolbar-broken-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:39:03.065 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__toolbar-broken-calibratio...)\""]}
{"run": "s54c", "pass": 2, "name": "toolbar-broken-calibration", "sha256": "f5f61abe9857e5473452ba35d0a941c4ded9461361e8be9beeb70d6a329e5a80", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00002__wfv__toolbar-broken-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:28.583 'Word found unreadable content in 00002__wfv__toolbar-broken-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:29.365 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__toolbar-broken-calibratio...)\""]}
{"run": "s54c", "pass": 1, "name": "toolbar-broken-upper-xml", "sha256": "cfeb78d2c8ceb5466d9e38dcecec0d8127f1dea2761ae8c3bd2dc5e4f2701ab4", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00003__wfv__toolbar-broken-upper-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:06.480 'Word found unreadable content in 00003__wfv__toolbar-broken-upper-xml.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:39:07.296 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__toolbar-broken-upper-xml....)\""]}
{"run": "s54c", "pass": 2, "name": "toolbar-broken-upper-xml", "sha256": "cfeb78d2c8ceb5466d9e38dcecec0d8127f1dea2761ae8c3bd2dc5e4f2701ab4", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00003__wfv__toolbar-broken-upper-xml.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:32.763 'Word found unreadable content in 00003__wfv__toolbar-broken-upper-xml.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:33.548 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__toolbar-broken-upper-xml....)\""]}
{"run": "s54c", "pass": 1, "name": "s54c-control-minimal-end", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:39:09+00:00", "staged": "00000__wfv__s54c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54c", "pass": 2, "name": "s54c-control-minimal-end", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:40:35+00:00", "staged": "00000__wfv__s54c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 1, "name": "s54d-control-minimal", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00005__wfv__s54d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 2, "name": "s54d-control-minimal", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00005__wfv__s54d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 1, "name": "dup-fonttable-package-rels", "sha256": "2c9929f882aaca637d3675e93383983db5b2ff5eb404d50f9a7b57109508c291", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00000__wfv__dup-fonttable-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-fonttable-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 2, "name": "dup-fonttable-package-rels", "sha256": "2c9929f882aaca637d3675e93383983db5b2ff5eb404d50f9a7b57109508c291", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00000__wfv__dup-fonttable-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-fonttable-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 1, "name": "dup-websettings-package-rels", "sha256": "bd8b65c79c3a50832dd2f97807d79483ef7f2a3cc6dbbcbb7b034e911c27d293", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00003__wfv__dup-websettings-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-websettings-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 2, "name": "dup-websettings-package-rels", "sha256": "bd8b65c79c3a50832dd2f97807d79483ef7f2a3cc6dbbcbb7b034e911c27d293", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00003__wfv__dup-websettings-package-rels.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF dup-websettings-package-rels_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 1, "name": "dup-websettings-glossary-sidecar", "sha256": "017b32dfe1f02cd6328e070f2fec2bbaebfd6ade8277658cb59e34af9de61977", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00002__wfv__dup-websettings-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:21.780 'Word found unreadable content in 00002__wfv__dup-websettings-glossary-sidecar.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:39:22.565 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__dup-websettings-glossary-...)\""]}
{"run": "s54d", "pass": 2, "name": "dup-websettings-glossary-sidecar", "sha256": "017b32dfe1f02cd6328e070f2fec2bbaebfd6ade8277658cb59e34af9de61977", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00002__wfv__dup-websettings-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:48.086 'Word found unreadable content in 00002__wfv__dup-websettings-glossary-sidecar.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:48.985 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__dup-websettings-glossary-...)\""]}
{"run": "s54d", "pass": 1, "name": "dup-theme-glossary-sidecar", "sha256": "e214957b33d64daf293f3e8c27d27adbdc887dc7f1219ed8339d904708c4766b", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00001__wfv__dup-theme-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:39:17.598 'Word found unreadable content in 00001__wfv__dup-theme-glossary-sidecar.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:39:18.416 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__dup-theme-glossary-sideca...)\""]}
{"run": "s54d", "pass": 2, "name": "dup-theme-glossary-sidecar", "sha256": "e214957b33d64daf293f3e8c27d27adbdc887dc7f1219ed8339d904708c4766b", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00001__wfv__dup-theme-glossary-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 09:40:43.655 'Word found unreadable content in 00001__wfv__dup-theme-glossary-sidecar.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 09:40:44.627 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__dup-theme-glossary-sideca...)\""]}
{"run": "s54d", "pass": 1, "name": "s54d-control-minimal-end", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:39:23+00:00", "staged": "00004__wfv__s54d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s54d", "pass": 2, "name": "s54d-control-minimal-end", "sha256": "e9022a75397b8b4ec966cb931f5cb0e7c97d9ffda8719aadec4d012a5bb57a89", "observedAt": "2026-10-26T13:40:50+00:00", "staged": "00004__wfv__s54d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s54d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 54 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s54builder.mts`:

```ts
// Session 54 (2026-10-26): the shapes three follow-ups need before they land.
// - s54a/s54b (#734): a broken relationship Target the rels-broken verdict reads. Layer 158's lane decides it from the
//   resolved part (a relationships part, or a customXml part outside word/) instead of the Target's spelling, which
//   changes the verdict of spellings Word never saw: the injected ones (media/_rels/x.png, notes.rels,
//   word/../customXml/x.png), a reached glossary's ../customXml/ target, a target above the package root, and the
//   absolute, backslash and escaped spellings of the blocking ../customXml/item1.xml (vectors.docx's shape, the
//   calibration). A broken media target is the tolerated calibration.
// - s54c (#743): the attached-toolbar walk finds the part and its sidecar by literal name. The Word-clean and the
//   Word-refused toolbar fixtures, re-zipped unchanged (calibrations), the clean one with its sidecar spelled .RELS and
//   with an empty wne:toolbarData r:id, and the refused one with the part and sidecar spelled .XML.
// - s54d (#744): the four duplicate cells session 50 did not show: two fontTable and two webSettings relationships in
//   _rels/.rels, two webSettings and two theme relationships in a reached glossary's sidecar.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s54a pnpm exec tsx s54builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN_TYPE = `${WML}.document.main+xml`;
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

/** A Word-clean fixture's theme part (Word 16.115 clean-open in the manifest). */
const THEME_XML = await (async () => {
    const zip = await JSZip.loadAsync(readFileSync("tests/fixtures/working/package.drawing-arc-radius-integer.docx"));
    const file = zip.file("word/theme/theme1.xml");
    if (!file) throw new Error("theme fixture lost word/theme/theme1.xml");
    return file.async("string");
})();

type Kind = "numbering" | "settings" | "fontTable" | "webSettings" | "theme";
/** The relationship segment, the part body and the content type of each kind (the bodies session 47 used). */
const KINDS: Record<Kind, { root: string; ct: string }> = {
    numbering: { root: `${XML_DECL}<w:numbering xmlns:w="${W}"/>`, ct: `${WML}.numbering+xml` },
    settings: { root: `${XML_DECL}<w:settings xmlns:w="${W}"/>`, ct: `${WML}.settings+xml` },
    fontTable: { root: `${XML_DECL}<w:fonts xmlns:w="${W}"/>`, ct: `${WML}.fontTable+xml` },
    webSettings: { root: `${XML_DECL}<w:webSettings xmlns:w="${W}"/>`, ct: `${WML}.webSettings+xml` },
    theme: { root: THEME_XML, ct: "application/vnd.openxmlformats-officedocument.theme+xml" },
};
/** Where a kind's parts live: `theme/theme1.xml` for the theme, `<kind>.xml` otherwise. */
const fileOf = (kind: Kind, n: 1 | 2) => (kind === "theme" ? `theme/theme${n}.xml` : `${kind}${n === 1 ? "" : "2"}.xml`);

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${REL}/${segment}" Target="${target}"/>`;
const relsPart = (body: string) =>
    `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/** The minimal package plus `word/<file of kind>` related from the main document's sidecar as rId2. */
const withRelated = (kind: Kind, type = KINDS[kind].ct): Record<string, string> => ({
    ...P,
    [`word/${fileOf(kind, 1)}`]: KINDS[kind].root,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", kind, fileOf(kind, 1))),
    [CT]: overrides(P[CT]!, [`word/${fileOf(kind, 1)}`, type]),
});
/** {@link withRelated} with the Override of the related part (or of `part`) carrying `type`. */
const relatedTyped = (kind: Kind, type: string) => buildDocx(withRelated(kind, type));
const retyped = (part: string, own: string, type: string) =>
    buildDocx({
        ...P,
        [CT]: replaceOnce(
            P[CT]!,
            `<Override PartName="/${part}" ContentType="${own}"/>`,
            `<Override PartName="/${part}" ContentType="${type}"/>`,
        ),
    });
const mainTyped = (type: string) => retyped("word/document.xml", MAIN_TYPE, type);

/** Session 45's refused shape: two relationships of `kind` to two parts in the main document's sidecar. */
const dupInMainRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rId3", kind, fileOf(kind, 2))),
        [CT]: overrides(parts[CT]!, [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
/** The main document's own `kind` relationship, and two more of `kind` in `_rels/.rels` (s49c's styles shape). */
const dupInPackageRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "_rels/.rels": appendRels(
            P["_rels/.rels"]!,
            `${relationship("rId8", kind, `word/${fileOf(kind, 1)}`)}${relationship("rId9", kind, `word/${fileOf(kind, 2)}`)}`,
        ),
        [CT]: overrides(parts[CT]!, [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
const HEADER = `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`;
/** The main document's own `kind` relationship, and a referenced header whose sidecar holds two of `kind`. */
const dupInHeaderRels = (kind: Kind) => {
    const parts = withRelated(kind);
    return buildDocx({
        ...parts,
        [`word/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "word/document.xml": replaceOnce(
            replaceOnce(P["word/document.xml"]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
            "<w:sectPr>",
            `<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>`,
        ),
        "word/header9.xml": HEADER,
        "word/_rels/header9.xml.rels": relsPart(
            `${relationship("rId1", kind, fileOf(kind, 1))}${relationship("rId2", kind, fileOf(kind, 2))}`,
        ),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header9.xml")),
        [CT]: overrides(parts[CT]!, ["word/header9.xml", `${WML}.header+xml`], [`word/${fileOf(kind, 2)}`, KINDS[kind].ct]),
    });
};
const GLOSSARY =
    `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Part</w:t></w:r></w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/** A reached glossary whose own sidecar holds two relationships of `kind` to two parts in its folder (s49c's shape). */
const dupInGlossaryRels = (kind: Kind) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        [`word/glossary/${fileOf(kind, 1)}`]: KINDS[kind].root,
        [`word/glossary/${fileOf(kind, 2)}`]: KINDS[kind].root,
        "word/glossary/_rels/document.xml.rels": relsPart(
            `${relationship("rId1", kind, fileOf(kind, 1))}${relationship("rId2", kind, fileOf(kind, 2))}`,
        ),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
        [CT]: overrides(
            P[CT]!,
            ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
            [`word/glossary/${fileOf(kind, 1)}`, KINDS[kind].ct],
            [`word/glossary/${fileOf(kind, 2)}`, KINDS[kind].ct],
        ),
    });

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

/** The minimal package plus one relationship of `segment` from the main document's sidecar to an absent `target`. */
const brokenFromMain = (segment: string, target: string) =>
    buildDocx({ ...P, [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId9", segment, target)) });
/** A reached glossary whose own sidecar relates `segment` to an absent `target` (s49c's glossary shape). */
const brokenFromGlossary = (segment: string, target: string) =>
    buildDocx({
        ...P,
        "word/glossary/document.xml": GLOSSARY,
        "word/glossary/_rels/document.xml.rels": relsPart(relationship("rId1", segment, target)),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
        [CT]: overrides(P[CT]!, ["word/glossary/document.xml", `${WML}.document.glossary+xml`]),
    });

const CLEAN_TOOLBAR = "tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx";
const BROKEN_TOOLBAR = "tests/fixtures/broken/package.word-attached-toolbar-utf8.docx";
/** `fixture` re-zipped with `edit` applied to its entries (renames, text replacements). */
const rezip = async (fixture: string, edit: (zip: JSZip) => Promise<void> = async () => {}) => {
    const zip = await JSZip.loadAsync(readFileSync(fixture));
    await edit(zip);
    return zip.generateAsync({ type: "uint8array", compression: "DEFLATE" });
};
const rename = async (zip: JSZip, from: string, to: string) => {
    const file = zip.file(from);
    if (!file) throw new Error(`no ${from}`);
    const bytes = await file.async("uint8array");
    zip.remove(from);
    zip.file(to, bytes);
};
const emptyToolbarId = async (zip: JSZip) => {
    const file = zip.file("word/customizations.xml");
    if (!file) throw new Error("no word/customizations.xml");
    const xml = await file.async("string");
    const ids = xml.match(/r:id="[^"]*"/g) ?? [];
    if (ids.length !== 1) throw new Error(`expected one r:id, found ${ids.length}`);
    zip.file("word/customizations.xml", xml.replace(ids[0]!, 'r:id=""'));
};

const chunks: Record<string, Row[]> = {
    s54a: withControls("s54a", [
        [
            "broken-customxml-calibration",
            "#734 calibration (vectors.docx's shape): a customXml relationship from the main document's sidecar to an absent ../customXml/item1.xml",
            () => brokenFromMain("customXml", "../customXml/item1.xml"),
        ],
        [
            "broken-customxml-absolute",
            "#734: the same target spelled /customXml/item1.xml",
            () => brokenFromMain("customXml", "/customXml/item1.xml"),
        ],
        [
            "broken-customxml-backslash",
            "#734: the same target spelled ..\\customXml\\item1.xml",
            () => brokenFromMain("customXml", "..\\customXml\\item1.xml"),
        ],
        [
            "broken-customxml-escaped",
            "#734: the same target spelled ../CUSTOMXML/%69tem1.xml",
            () => brokenFromMain("customXml", "../CUSTOMXML/%69tem1.xml"),
        ],
        [
            "broken-customxml-above-root",
            "#734: the same target spelled ../../customXml/item1.xml (above the package root)",
            () => brokenFromMain("customXml", "../../customXml/item1.xml"),
        ],
    ]),
    s54b: withControls("s54b", [
        [
            "broken-media-calibration",
            "#734 calibration (tolerated): an image relationship from the main document's sidecar to an absent media/image9.png",
            () => brokenFromMain("image", "media/image9.png"),
        ],
        [
            "broken-image-media-rels-folder",
            "#734: an image relationship to an absent media/_rels/x.png",
            () => brokenFromMain("image", "media/_rels/x.png"),
        ],
        ["broken-image-notes-rels", "#734: an image relationship to an absent notes.rels", () => brokenFromMain("image", "notes.rels")],
        [
            "broken-image-word-customxml",
            "#734: an image relationship to an absent word/../customXml/x.png (resolves to word/customXml/x.png)",
            () => brokenFromMain("image", "word/../customXml/x.png"),
        ],
        [
            "broken-customxml-from-glossary",
            "#734: a reached glossary's customXml relationship to an absent ../customXml/item1.xml (resolves under word/)",
            () => brokenFromGlossary("customXml", "../customXml/item1.xml"),
        ],
    ]),
    s54c: withControls("s54c", [
        ["toolbar-clean-calibration", "#743 calibration: the Word-clean toolbar fixture re-zipped unchanged", () => rezip(CLEAN_TOOLBAR)],
        [
            "toolbar-clean-sidecar-upper-rels",
            "#743: the same with its sidecar stored as word/_rels/customizations.xml.RELS",
            () => rezip(CLEAN_TOOLBAR, (zip) => rename(zip, "word/_rels/customizations.xml.rels", "word/_rels/customizations.xml.RELS")),
        ],
        ["toolbar-clean-empty-id", '#743: the same with wne:toolbarData r:id=""', () => rezip(CLEAN_TOOLBAR, emptyToolbarId)],
        [
            "toolbar-broken-calibration",
            "#743 calibration: the Word-refused toolbar fixture re-zipped unchanged",
            () => rezip(BROKEN_TOOLBAR),
        ],
        [
            "toolbar-broken-upper-xml",
            "#743: the same with word/customizations.xml and its sidecar stored with .XML spellings",
            () =>
                rezip(BROKEN_TOOLBAR, async (zip) => {
                    await rename(zip, "word/customizations.xml", "word/customizations.XML");
                    await rename(zip, "word/_rels/customizations.xml.rels", "word/_rels/customizations.XML.rels");
                }),
        ],
    ]),
    s54d: withControls("s54d", [
        [
            "dup-fonttable-package-rels",
            "#744: the main document's fontTable relationship, and two more fontTable relationships in _rels/.rels",
            () => dupInPackageRels("fontTable"),
        ],
        [
            "dup-websettings-package-rels",
            "#744: the main document's webSettings relationship, and two more webSettings relationships in _rels/.rels",
            () => dupInPackageRels("webSettings"),
        ],
        [
            "dup-websettings-glossary-sidecar",
            "#744: a reached glossary's sidecar holds two webSettings relationships to two parts",
            () => dupInGlossaryRels("webSettings"),
        ],
        [
            "dup-theme-glossary-sidecar",
            "#744: a reached glossary's sidecar holds two theme relationships to two parts",
            () => dupInGlossaryRels("theme"),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-54 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s54a", "s54b", "s54c", "s54d")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s54/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-54 parts of docs/plans/evidence/word-probes-2026-10-24.md into s54/section.md.

Reads the chunk's specimens.jsonl (validator columns at 0b26c414, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s54/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s54a", "s54b", "s54c", "s54d")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s54/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 54: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 0b26c414",
    "",
    "The shapes three follow-ups need before they land: the broken relationship targets whose `rels-broken` verdict "
    "[#734](https://github.com/jandira-tech/docx-validate/issues/734) moves from the Target's spelling to the part it resolves to; the "
    "attached-toolbar spellings and the empty id of [#743](https://github.com/jandira-tech/docx-validate/issues/743) (the review of layers "
    "151–155, findings 2, 3 and S1); and the four duplicate cells session 50 did not show "
    "([#744](https://github.com/jandira-tech/docx-validate/issues/744), finding 4). Each chunk ran twice, as two separate driver runs of "
    "byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 27 rows "
    "agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A `customXml` relationship from the main document's relationships part to an absent package-root `customXml/item1.xml` gets the "
    "recovery offer however the Target spells it: `../customXml/item1.xml` (vectors.docx's shape, the calibration), `/customXml/item1.xml`, "
    "`..\\customXml\\item1.xml`, `../CUSTOMXML/%69tem1.xml`, and `../../customXml/item1.xml`, whose extra `..` stays at the package root as "
    "RFC 3986 removes dot segments. Word-valid at 0b26c414 rejects only the calibration and the last: three false negatives.",
    "- An image relationship to an absent `media/_rels/x.png`, `notes.rels` or `word/../customXml/x.png` opens clean, as the broken "
    "`media/image9.png` calibration does, and so does a reached glossary's `customXml` relationship to an absent `../customXml/item1.xml` "
    "(which resolves to `word/customXml/item1.xml`). Word-valid at 0b26c414 rejects all four by their spelling: false positives.",
    "- The Word-clean toolbar fixture (`tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx`, re-zipped) opens clean "
    "unchanged, with its relationships part stored as `word/_rels/customizations.xml.RELS`, and with `wne:toolbarData r:id=\"\"`. "
    "Word-valid rejects the `.RELS` spelling through `word-attached-toolbar-relationship`: a false positive. The Word-refused fixture "
    "(`tests/fixtures/broken/package.word-attached-toolbar-utf8.docx`) gets the recovery offer unchanged and with `word/customizations.xml` "
    "and its relationships part stored with `.XML` spellings; word-valid passes the `.XML` spelling: a false negative.",
    "- Two fontTable or two webSettings relationships in `_rels/.rels`, beside the main document's own, open clean; two webSettings or two "
    "theme relationships in a reached glossary's relationships part get the recovery offer. Word-valid agrees on all four.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 0b26c414 | strict at 0b26c414 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 54</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 54 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s54builder.mts", ROOT / "s54builder.mts", "ts"), ("compare.py", ROOT / "s54/compare.py", "python"),
                         ("section.py", ROOT / "s54/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s54/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 55: 14:37Z–14:51Z on 2026-10-26, validator columns at 42600284

The shapes the review of layers 161–165 asked Word about: a header Word reads stored with no relationships part, whose references layer 161 handed to `rels-missing-sidecar` ([#751](https://github.com/jandira-tech/docx-validate/issues/751), finding 1), and a relationship whose TargetMode is spelled `external`, and a `c:chart` naming its relationship in both relationships namespaces ([#753](https://github.com/jandira-tech/docx-validate/issues/753), findings 6 and 7), with s55d and s55e added after the first three chunks to separate those two shapes from their confounders and to bound the TargetMode rule. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 33 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A header the body references, stored as `word/header1.xml` with no relationships part, gets the recovery offer when it holds a `c:chart r:id="rId1"`, an `o:OLEObject r:id="rId1"`, or a `dgm:relIds` naming all four parts, as the same header does with a relationships part that lacks `rId1` (the calibration); with no `r:` reference it opens clean. Word-valid at 42600284 passes all three: false negatives.
- A relationship whose TargetMode is spelled `external` gets the recovery offer whether a `c:chart` names it, it is the diagramData relationship of session 46's word-clean-strict01 SmartArt, or it is an unreferenced hyperlink relationship in the main document's relationships part; spelled `Internal` or `External` the same packages open clean. Word reads the spelling, not the reference. The unreferenced hyperlink relationship also gets the recovery offer with TargetMode `external` in the package's `_rels/.rels`, and with `External ` (trailing space) or an empty TargetMode in the main document's relationships part; with `external` in a referenced header's own relationships part it opens clean, as with `External`. Word-valid at 42600284 passes all six refused shapes: false negatives.
- A `c:chart` carrying both `r:id` and the ISO Strict `rs:id` cannot be opened (open error, no recovery offer) whether one of the two is empty or both name the real chart relationship; `rs:id` alone in the Transitional document opens clean and draws the chart. Word refuses the second namespace, not the empty id. Word-valid at 42600284 passes all three: false negatives.

| Run    | Observed             | Specimen                                                    | Shape                                                                                                                                   | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 42600284                      | strict at 42600284                                                                                                      |
| ------ | -------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `s55a` | 14:37:34Z, 14:42:56Z | `s55a-control-minimal`                                      | control                                                                                                                                 | `77911632378a0c59` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55a` | 14:37:34Z, 14:42:56Z | `header1-nosidecar-chart`                                   | #751: a referenced word/header1.xml with no relationships part holding c:chart r:id="rId1"                                              | `0c17fe98f3e1b500` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `rels-missing-sidecar`, `paraid-missing-element`                                                               |
| `s55a` | 14:37:34Z, 14:42:56Z | `header1-nosidecar-oleobject`                               | #751: the same holding o:OLEObject r:id="rId1"                                                                                          | `34fe5c44836c900a` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `rels-missing-sidecar`, `paraid-missing-element`                                                               |
| `s55a` | 14:37:34Z, 14:42:56Z | `header1-nosidecar-relids`                                  | #751: the same holding dgm:relIds r:dm="rId1" r:lo="rId2" r:qs="rId3" r:cs="rId4" (all four, so the schema holds)                       | `39fec363bd5b01e8` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `paraid-missing-element`                                                                                       |
| `s55a` | 14:37:34Z, 14:42:56Z | `header1-sidecar-no-rid1-calibration`                       | #751 calibration: the same header with c:chart r:id="rId1" and its relationships part present, holding only an image rId2               | `3d851542cfaf783b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-reference-relationship` | invalid: `paraid-missing-element`, `word-part-reference-relationship`                                                   |
| `s55a` | 14:37:34Z, 14:42:56Z | `header1-nosidecar-no-reference-calibration`                | #751 calibration: the same header with no relationships part and no r: reference                                                        | `d3dae6d4ea8625aa` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`                                                                                       |
| `s55a` | 14:37:34Z, 14:42:56Z | `s55a-control-minimal-end`                                  | control                                                                                                                                 | `78f982860ac99baf` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55b` | 14:40:36Z, 14:43:41Z | `s55b-control-minimal`                                      | control                                                                                                                                 | `f52a9fd507089864` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55b` | 14:40:36Z, 14:43:41Z | `chart-plain-calibration`                                   | #753 calibration: c:chart r:id="rId9" names a real chart relationship (no TargetMode)                                                   | `28ade628d257b5b0` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`                                                                                       |
| `s55b` | 14:40:36Z, 14:43:41Z | `chart-targetmode-internal-calibration`                     | #753 calibration: the same relationship with TargetMode="Internal"                                                                      | `d5261aedec66660e` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`                                                                                       |
| `s55b` | 14:40:36Z, 14:43:41Z | `chart-targetmode-lowercase-external`                       | #753: the same relationship with TargetMode="external"                                                                                  | `a77a11d136454bfa` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55b` | 14:40:36Z, 14:43:41Z | `chart-empty-r-id-real-rs-id`                               | #753: c:chart r:id="" rs:id="rId9" (rs: the ISO Strict relationships namespace)                                                         | `96f7e8b6677fba4e` | open-error     | open-error     | open-error                 | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55b` | 14:40:36Z, 14:43:41Z | `chart-empty-rs-id-real-r-id`                               | #753: c:chart rs:id="" r:id="rId9"                                                                                                      | `62c818e6b5606283` | open-error     | open-error     | open-error                 | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55b` | 14:40:36Z, 14:43:41Z | `s55b-control-minimal-end`                                  | control                                                                                                                                 | `c6330dd00a5477e0` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55c` | 14:41:02Z, 14:44:05Z | `s55c-control-minimal`                                      | control                                                                                                                                 | `c6330dd00a5477e0` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55c` | 14:41:02Z, 14:44:05Z | `strict01-calibration`                                      | calibration: word-clean-strict01 unmodified (session 52 s52d: clean)                                                                    | `a2d1d47f9da0b202` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                             |
| `s55c` | 14:41:02Z, 14:44:05Z | `strict01-data-targetmode-internal-calibration`             | #753 calibration: word-clean-strict01 with diagramData rId35 TargetMode="Internal"                                                      | `d1abd27b7fa94512` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                             |
| `s55c` | 14:41:02Z, 14:44:05Z | `strict01-data-targetmode-lowercase-external`               | #753: word-clean-strict01 with diagramData rId35 TargetMode="external"                                                                  | `9c97f4f2ade45aea` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s55c` | 14:41:02Z, 14:44:05Z | `s55c-control-minimal-end`                                  | control                                                                                                                                 | `075b4d10f8f3e996` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55d` | 14:45:32Z, 14:46:05Z | `s55d-control-minimal`                                      | control                                                                                                                                 | `23c5038e1dd4a7fd` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55d` | 14:45:32Z, 14:46:05Z | `chart-both-ids-real`                                       | #753 calibration: c:chart r:id="rId9" rs:id="rId9" (both relationships namespaces, both real)                                           | `3e0499a0d2f7a417` | open-error     | open-error     | open-error                 | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55d` | 14:45:32Z, 14:46:05Z | `chart-rs-id-only`                                          | #753 calibration: c:chart rs:id="rId9" alone in a Transitional document                                                                 | `58e9a760c16b13b1` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55d` | 14:45:32Z, 14:46:05Z | `hyperlink-unreferenced-targetmode-external-calibration`    | #753 calibration: an unreferenced hyperlink relationship with TargetMode="External"                                                     | `bf3a0f4844707acf` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55d` | 14:45:32Z, 14:46:05Z | `hyperlink-unreferenced-targetmode-lowercase-external`      | #753: an unreferenced hyperlink relationship with TargetMode="external"                                                                 | `ca9102df80f7bc53` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `xsd-summary`, `xsd-error`                                                                                     |
| `s55d` | 14:45:32Z, 14:46:05Z | `s55d-control-minimal-end`                                  | control                                                                                                                                 | `23c5038e1dd4a7fd` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55e` | 14:49:46Z, 14:51:47Z | `s55e-control-minimal`                                      | control                                                                                                                                 | `7bd93e76bd6c60f4` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55e` | 14:49:46Z, 14:51:47Z | `package-rels-hyperlink-targetmode-lowercase-external`      | #753 scope: an unreferenced hyperlink relationship in _rels/.rels with TargetMode="external"                                            | `73fd95fd024e5aee` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `xsd-summary`, `xsd-error`                                                                                     |
| `s55e` | 14:49:46Z, 14:51:47Z | `package-rels-hyperlink-targetmode-external-calibration`    | #753 scope calibration: the same with TargetMode="External"                                                                             | `fa47c811fa315ea3` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |
| `s55e` | 14:49:46Z, 14:51:47Z | `header-rels-hyperlink-targetmode-lowercase-external`       | #753 scope: a referenced header's own relationships part holding only an unreferenced hyperlink relationship with TargetMode="external" | `fa04cbe8e3671e36` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                           |
| `s55e` | 14:49:46Z, 14:51:47Z | `header-rels-hyperlink-targetmode-external-calibration`     | #753 scope calibration: the same with TargetMode="External"                                                                             | `4cbe23b0f7655b6e` | clean-open     | clean-open     | clean-open                 | valid                                       | invalid: `paraid-missing-element`                                                                                       |
| `s55e` | 14:49:46Z, 14:51:47Z | `hyperlink-unreferenced-targetmode-external-trailing-space` | #753 scope: an unreferenced hyperlink relationship in the main document's relationships part with TargetMode="External "                | `11747902572a966d` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `xsd-summary`, `xsd-error`                                                                                     |
| `s55e` | 14:49:46Z, 14:51:47Z | `hyperlink-unreferenced-targetmode-empty`                   | #753 scope: the same with TargetMode=""                                                                                                 | `76274697d01e3dad` | repair-warning | repair-warning | unreadable-content-warning | valid                                       | invalid: `xsd-summary`, `xsd-error`                                                                                     |
| `s55e` | 14:49:46Z, 14:51:47Z | `s55e-control-minimal-end`                                  | control                                                                                                                                 | `7bd93e76bd6c60f4` | clean-open     | clean-open     | clean-open                 | valid                                       | valid                                                                                                                   |

<details><summary>Raw records, session 55</summary>

```jsonl
{"run": "s55a", "pass": 1, "name": "s55a-control-minimal", "sha256": "77911632378a0c59f55a72d53d41c6d0a124c4986ede0382e5753280661b636e", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00006__wfv__s55a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55a", "pass": 2, "name": "s55a-control-minimal", "sha256": "77911632378a0c59f55a72d53d41c6d0a124c4986ede0382e5753280661b636e", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00006__wfv__s55a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55a", "pass": 1, "name": "header1-nosidecar-chart", "sha256": "0c17fe98f3e1b500977888f0a319631869a3c88dbac3d34467b952692d7696c2", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00000__wfv__header1-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:35:38.069 \"Word found unreadable content in 00000__wfv__header1-nosidecar-chart.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s55a", "pass": 2, "name": "header1-nosidecar-chart", "sha256": "0c17fe98f3e1b500977888f0a319631869a3c88dbac3d34467b952692d7696c2", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00000__wfv__header1-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:41:16.606 'Word found unreadable content in 00000__wfv__header1-nosidecar-chart.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:41:17.151 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header1-nosidecar-chart.docx)\""]}
{"run": "s55a", "pass": 1, "name": "header1-nosidecar-oleobject", "sha256": "34fe5c44836c900ab3c454ec0dd6c8fd630b2c0f98e077315ee0f346f26ca9fd", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00002__wfv__header1-nosidecar-oleobject.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:35:52.088 \"Word found unreadable content in 00002__wfv__header1-nosidecar-oleobject.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s55a", "pass": 2, "name": "header1-nosidecar-oleobject", "sha256": "34fe5c44836c900ab3c454ec0dd6c8fd630b2c0f98e077315ee0f346f26ca9fd", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00002__wfv__header1-nosidecar-oleobject.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:41:33.873 \"Word found unreadable content in 00002__wfv__header1-nosidecar-oleobject.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s55a", "pass": 1, "name": "header1-nosidecar-relids", "sha256": "39fec363bd5b01e834611563bc143ca2aa7c8abb12c59276234097ebdb4dd416", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00003__wfv__header1-nosidecar-relids.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:36:44.502 Microsoft Word, Word found unreadable content in 00003__wfv__header1-nosidecar-relids.docx. Do you w … t? If you trust the source of this document, click Yes."]}
{"run": "s55a", "pass": 2, "name": "header1-nosidecar-relids", "sha256": "39fec363bd5b01e834611563bc143ca2aa7c8abb12c59276234097ebdb4dd416", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00003__wfv__header1-nosidecar-relids.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:42:18.423 Microsoft Word, Word found unreadable content in 00003__wfv__header1-nosidecar-relids.docx. Do you w … t? If you trust the source of this document, click Yes."]}
{"run": "s55a", "pass": 1, "name": "header1-sidecar-no-rid1-calibration", "sha256": "3d851542cfaf783b2dfab50526b7e7b20d9b0654a69f138d63cf9c4b21c153d9", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00004__wfv__header1-sidecar-no-rid1-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:37:33.158 Microsoft Word, Word found unreadable content in 00004__wfv__header1-sidecar-no-rid1-calibration.doc … t? If you trust the source of this document, click Yes.", "2026-10-26 10:37:33.846 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__header1-sidecar-no-rid1-c...)\""]}
{"run": "s55a", "pass": 2, "name": "header1-sidecar-no-rid1-calibration", "sha256": "3d851542cfaf783b2dfab50526b7e7b20d9b0654a69f138d63cf9c4b21c153d9", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00004__wfv__header1-sidecar-no-rid1-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:42:54.232 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__header1-sidecar-no-rid1-c...)'", "2026-10-26 10:42:54.403 \"Word found unreadable content in 00004__wfv__header1-sidecar-no-rid1-calibration.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s55a", "pass": 1, "name": "header1-nosidecar-no-reference-calibration", "sha256": "d3dae6d4ea8625aaa3633dcba59f486ad1caa2809b6c1b9713387f9daa67bdfc", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00001__wfv__header1-nosidecar-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header1-nosidecar-no-reference-calibration_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55a", "pass": 2, "name": "header1-nosidecar-no-reference-calibration", "sha256": "d3dae6d4ea8625aaa3633dcba59f486ad1caa2809b6c1b9713387f9daa67bdfc", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00001__wfv__header1-nosidecar-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header1-nosidecar-no-reference-calibration_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55a", "pass": 1, "name": "s55a-control-minimal-end", "sha256": "78f982860ac99baf1f600be6f79be2b40bb76b9ec4215ecc7bdc48a2b462e411", "observedAt": "2026-10-26T14:37:34+00:00", "staged": "00005__wfv__s55a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55a", "pass": 2, "name": "s55a-control-minimal-end", "sha256": "78f982860ac99baf1f600be6f79be2b40bb76b9ec4215ecc7bdc48a2b462e411", "observedAt": "2026-10-26T14:42:56+00:00", "staged": "00005__wfv__s55a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 1, "name": "s55b-control-minimal", "sha256": "f52a9fd507089864b5c880bbfb2e381caa05c14607502f867786c3f57a56f568", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00006__wfv__s55b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 2, "name": "s55b-control-minimal", "sha256": "f52a9fd507089864b5c880bbfb2e381caa05c14607502f867786c3f57a56f568", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00006__wfv__s55b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 1, "name": "chart-plain-calibration", "sha256": "28ade628d257b5b0365d27e4c6e44f4564324868d3b47beeed2a20ba49cc0015", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00002__wfv__chart-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-plain-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 2, "name": "chart-plain-calibration", "sha256": "28ade628d257b5b0365d27e4c6e44f4564324868d3b47beeed2a20ba49cc0015", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00002__wfv__chart-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-plain-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 1, "name": "chart-targetmode-internal-calibration", "sha256": "d5261aedec66660e4028dfc28b3d2ca28bfe8598c42ead956991ef4b9b5ace17", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00003__wfv__chart-targetmode-internal-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-targetmode-internal-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 2, "name": "chart-targetmode-internal-calibration", "sha256": "d5261aedec66660e4028dfc28b3d2ca28bfe8598c42ead956991ef4b9b5ace17", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00003__wfv__chart-targetmode-internal-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-targetmode-internal-calibration_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 1, "name": "chart-targetmode-lowercase-external", "sha256": "a77a11d136454bfa9f2ae6c0cf3fe1b4db45147499256e772e9b16339f33bb74", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00004__wfv__chart-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:40:06.145 \"Word found unreadable content in 00004__wfv__chart-targetmode-lowercase-external.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s55b", "pass": 2, "name": "chart-targetmode-lowercase-external", "sha256": "a77a11d136454bfa9f2ae6c0cf3fe1b4db45147499256e772e9b16339f33bb74", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00004__wfv__chart-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:43:28.524 'Word found unreadable content in 00004__wfv__chart-targetmode-lowercase-external.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:43:29.102 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__chart-targetmode-lowercas...)\""]}
{"run": "s55b", "pass": 1, "name": "chart-empty-r-id-real-rs-id", "sha256": "96f7e8b6677fba4e0b0543e10bbfbba53a5689f5d34d00c3f4482e4532474b1f", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00000__wfv__chart-empty-r-id-real-rs-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:38:57.672 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00000__wfv__chart-empty-r-id-real-rs-...)'"]}
{"run": "s55b", "pass": 2, "name": "chart-empty-r-id-real-rs-id", "sha256": "96f7e8b6677fba4e0b0543e10bbfbba53a5689f5d34d00c3f4482e4532474b1f", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00000__wfv__chart-empty-r-id-real-rs-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:43:20.006 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00000__wfv__chart-empty-r-id-real-rs-...)'"]}
{"run": "s55b", "pass": 1, "name": "chart-empty-rs-id-real-r-id", "sha256": "62c818e6b5606283021e96537fa9676cc9a27a40a5522818fcf58f273c59e078", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00001__wfv__chart-empty-rs-id-real-r-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:39:48.954 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … y converter. (00001__wfv__chart-empty-rs-id-real-r-...)"]}
{"run": "s55b", "pass": 2, "name": "chart-empty-rs-id-real-r-id", "sha256": "62c818e6b5606283021e96537fa9676cc9a27a40a5522818fcf58f273c59e078", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00001__wfv__chart-empty-rs-id-real-r-id.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:43:24.205 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__chart-empty-rs-id-real-r-...)'"]}
{"run": "s55b", "pass": 1, "name": "s55b-control-minimal-end", "sha256": "c6330dd00a5477e0486f993075ee9dc453ef5e0b47860188c65567203167e6b8", "observedAt": "2026-10-26T14:40:36+00:00", "staged": "00005__wfv__s55b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55b", "pass": 2, "name": "s55b-control-minimal-end", "sha256": "c6330dd00a5477e0486f993075ee9dc453ef5e0b47860188c65567203167e6b8", "observedAt": "2026-10-26T14:43:41+00:00", "staged": "00005__wfv__s55b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 1, "name": "s55c-control-minimal", "sha256": "c6330dd00a5477e0486f993075ee9dc453ef5e0b47860188c65567203167e6b8", "observedAt": "2026-10-26T14:41:02+00:00", "staged": "00001__wfv__s55c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 2, "name": "s55c-control-minimal", "sha256": "c6330dd00a5477e0486f993075ee9dc453ef5e0b47860188c65567203167e6b8", "observedAt": "2026-10-26T14:44:05+00:00", "staged": "00001__wfv__s55c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 1, "name": "strict01-calibration", "sha256": "a2d1d47f9da0b2020a73a560524fb4b49e63fbba77da9535b2d1e534bd599f36", "observedAt": "2026-10-26T14:41:02+00:00", "staged": "00002__wfv__strict01-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 2, "name": "strict01-calibration", "sha256": "a2d1d47f9da0b2020a73a560524fb4b49e63fbba77da9535b2d1e534bd599f36", "observedAt": "2026-10-26T14:44:05+00:00", "staged": "00002__wfv__strict01-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 1, "name": "strict01-data-targetmode-internal-calibration", "sha256": "d1abd27b7fa94512a043c2fb0398d02ab77a21bb63ba253ee73e7afda84e0ad1", "observedAt": "2026-10-26T14:41:02+00:00", "staged": "00003__wfv__strict01-data-targetmode-internal-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-data-targetmode-internal-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 2, "name": "strict01-data-targetmode-internal-calibration", "sha256": "d1abd27b7fa94512a043c2fb0398d02ab77a21bb63ba253ee73e7afda84e0ad1", "observedAt": "2026-10-26T14:44:05+00:00", "staged": "00003__wfv__strict01-data-targetmode-internal-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-data-targetmode-internal-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 1, "name": "strict01-data-targetmode-lowercase-external", "sha256": "9c97f4f2ade45aea01cc6395c855a2ab2f87db30b64a5324349d7d6a0d942d39", "observedAt": "2026-10-26T14:41:02+00:00", "staged": "00004__wfv__strict01-data-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:40:50.865 'Word found unreadable content in 00004__wfv__strict01-data-targetmode-lowercase-external.docx. Do y … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:40:51.754 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-data-targetmode-...)\""]}
{"run": "s55c", "pass": 2, "name": "strict01-data-targetmode-lowercase-external", "sha256": "9c97f4f2ade45aea01cc6395c855a2ab2f87db30b64a5324349d7d6a0d942d39", "observedAt": "2026-10-26T14:44:05+00:00", "staged": "00004__wfv__strict01-data-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:43:55.107 'Word found unreadable content in 00004__wfv__strict01-data-targetmode-lowercase-external.docx. Do y … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:43:55.970 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__strict01-data-targetmode-...)\""]}
{"run": "s55c", "pass": 1, "name": "s55c-control-minimal-end", "sha256": "075b4d10f8f3e996ca5da22289910f92ffffccfc5eddcd1c5c302b03b19e43a1", "observedAt": "2026-10-26T14:41:02+00:00", "staged": "00000__wfv__s55c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55c", "pass": 2, "name": "s55c-control-minimal-end", "sha256": "075b4d10f8f3e996ca5da22289910f92ffffccfc5eddcd1c5c302b03b19e43a1", "observedAt": "2026-10-26T14:44:05+00:00", "staged": "00000__wfv__s55c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 1, "name": "s55d-control-minimal", "sha256": "23c5038e1dd4a7fdc46d0c0e1be98a5301974c0a77f600a3494bad937f967758", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00005__wfv__s55d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 2, "name": "s55d-control-minimal", "sha256": "23c5038e1dd4a7fdc46d0c0e1be98a5301974c0a77f600a3494bad937f967758", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00005__wfv__s55d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 1, "name": "chart-both-ids-real", "sha256": "3e0499a0d2f7a41753d67c052f98884719a767019f157357521c6b5fa372d782", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00000__wfv__chart-both-ids-real.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:45:14.639 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ery converter.\\n(00000__wfv__chart-both-ids-real.docx)'"]}
{"run": "s55d", "pass": 2, "name": "chart-both-ids-real", "sha256": "3e0499a0d2f7a41753d67c052f98884719a767019f157357521c6b5fa372d782", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00000__wfv__chart-both-ids-real.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-26 10:45:47.809 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ery converter.\\n(00000__wfv__chart-both-ids-real.docx)'"]}
{"run": "s55d", "pass": 1, "name": "chart-rs-id-only", "sha256": "58e9a760c16b13b1c5b7fca07dd0b886a4cf98f0e31d8dc78ff4df9f4952eefe", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00001__wfv__chart-rs-id-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-rs-id-only_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 2, "name": "chart-rs-id-only", "sha256": "58e9a760c16b13b1c5b7fca07dd0b886a4cf98f0e31d8dc78ff4df9f4952eefe", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00001__wfv__chart-rs-id-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-rs-id-only_byword.pdf (19390 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 1, "name": "hyperlink-unreferenced-targetmode-external-calibration", "sha256": "bf3a0f4844707acfe84efaa75295192a19f6ff48c1d77be55aefcbd6b450921d", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00002__wfv__hyperlink-unreferenced-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF hyperlink-unreferenced-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 2, "name": "hyperlink-unreferenced-targetmode-external-calibration", "sha256": "bf3a0f4844707acfe84efaa75295192a19f6ff48c1d77be55aefcbd6b450921d", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00002__wfv__hyperlink-unreferenced-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF hyperlink-unreferenced-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 1, "name": "hyperlink-unreferenced-targetmode-lowercase-external", "sha256": "ca9102df80f7bc53b985209e0edcf97ac74450e1042efd44ea20566e49527455", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00003__wfv__hyperlink-unreferenced-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:45:18.927 'Word found unreadable content in 00003__wfv__hyperlink-unreferenced-targetmode-lowercase-exte.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:45:19.764 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__hyperlink-unreferenced-ta...)\""]}
{"run": "s55d", "pass": 2, "name": "hyperlink-unreferenced-targetmode-lowercase-external", "sha256": "ca9102df80f7bc53b985209e0edcf97ac74450e1042efd44ea20566e49527455", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00003__wfv__hyperlink-unreferenced-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:45:52.006 'Word found unreadable content in 00003__wfv__hyperlink-unreferenced-targetmode-lowercase-exte.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:45:52.870 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__hyperlink-unreferenced-ta...)\""]}
{"run": "s55d", "pass": 1, "name": "s55d-control-minimal-end", "sha256": "23c5038e1dd4a7fdc46d0c0e1be98a5301974c0a77f600a3494bad937f967758", "observedAt": "2026-10-26T14:45:32+00:00", "staged": "00004__wfv__s55d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55d", "pass": 2, "name": "s55d-control-minimal-end", "sha256": "23c5038e1dd4a7fdc46d0c0e1be98a5301974c0a77f600a3494bad937f967758", "observedAt": "2026-10-26T14:46:05+00:00", "staged": "00004__wfv__s55d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 1, "name": "s55e-control-minimal", "sha256": "7bd93e76bd6c60f4dd6b83c97d945addd2c4ca63b9ac36818ab5bb5fa5f48342", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00007__wfv__s55e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 2, "name": "s55e-control-minimal", "sha256": "7bd93e76bd6c60f4dd6b83c97d945addd2c4ca63b9ac36818ab5bb5fa5f48342", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00007__wfv__s55e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 1, "name": "package-rels-hyperlink-targetmode-lowercase-external", "sha256": "73fd95fd024e5aee91cc591e797386813ab055b693769aa290d585e198a107d7", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00005__wfv__package-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:48:30.362 \"Word found unreadable content in 00005__wfv__package-rels-hyperlink-targetmode-lowercase-exte.... D … ? If you trust the source of this document, click Yes.\"", "2026-10-26 10:48:30.363 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package-rels-hyperlink-ta...)\""]}
{"run": "s55e", "pass": 2, "name": "package-rels-hyperlink-targetmode-lowercase-external", "sha256": "73fd95fd024e5aee91cc591e797386813ab055b693769aa290d585e198a107d7", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00005__wfv__package-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:51:02.848 \"Word found unreadable content in 00005__wfv__package-rels-hyperlink-targetmode-lowercase-exte.... D … ? If you trust the source of this document, click Yes.\"", "2026-10-26 10:51:02.848 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__package-rels-hyperlink-ta...)\""]}
{"run": "s55e", "pass": 1, "name": "package-rels-hyperlink-targetmode-external-calibration", "sha256": "fa47c811fa315ea3b3517a931159d78749d4013f1a9d3b00f5a44f9c4a20cf86", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00004__wfv__package-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-rels-hyperlink-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 2, "name": "package-rels-hyperlink-targetmode-external-calibration", "sha256": "fa47c811fa315ea3b3517a931159d78749d4013f1a9d3b00f5a44f9c4a20cf86", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00004__wfv__package-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-rels-hyperlink-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 1, "name": "header-rels-hyperlink-targetmode-lowercase-external", "sha256": "fa04cbe8e3671e3625a30dbb4149f86608572f00a9388d346cdcb6c49cdbaec2", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00001__wfv__header-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-rels-hyperlink-targetmode-lowercase-external_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 2, "name": "header-rels-hyperlink-targetmode-lowercase-external", "sha256": "fa04cbe8e3671e3625a30dbb4149f86608572f00a9388d346cdcb6c49cdbaec2", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00001__wfv__header-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-rels-hyperlink-targetmode-lowercase-external_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 1, "name": "header-rels-hyperlink-targetmode-external-calibration", "sha256": "4cbe23b0f7655b6e8a33b3eadf6826d4263c032a084873e4379dc7c5bd151f04", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00000__wfv__header-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-rels-hyperlink-targetmode-external-calibration_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 2, "name": "header-rels-hyperlink-targetmode-external-calibration", "sha256": "4cbe23b0f7655b6e8a33b3eadf6826d4263c032a084873e4379dc7c5bd151f04", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00000__wfv__header-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-rels-hyperlink-targetmode-external-calibration_byword.pdf (15927 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 1, "name": "hyperlink-unreferenced-targetmode-external-trailing-space", "sha256": "11747902572a966d18ef5c76c6753fb273ea6eff00dc123d48fc0b73920eeb75", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00003__wfv__hyperlink-unreferenced-targetmode-external-trailing-space.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:48:24.548 Microsoft Word, Word found unreadable content in 00003__wfv__hyperlink-unreferenced-targetmode-exter … t? If you trust the source of this document, click Yes.", "2026-10-26 10:49:02.394 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__hyperlink-unreferenced-ta...)\""]}
{"run": "s55e", "pass": 2, "name": "hyperlink-unreferenced-targetmode-external-trailing-space", "sha256": "11747902572a966d18ef5c76c6753fb273ea6eff00dc123d48fc0b73920eeb75", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00003__wfv__hyperlink-unreferenced-targetmode-external-trailing-space.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:50:57.236 'Word found unreadable content in 00003__wfv__hyperlink-unreferenced-targetmode-external-trail.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:51:41.951 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00003__wfv__hyperlink-unreferenced-ta...)'"]}
{"run": "s55e", "pass": 1, "name": "hyperlink-unreferenced-targetmode-empty", "sha256": "76274697d01e3dadb522d625f2dee12ca8c010e51535f0862ea3af3b853ebb85", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00002__wfv__hyperlink-unreferenced-targetmode-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:47:38.720 'Word found unreadable content in 00002__wfv__hyperlink-unreferenced-targetmode-empty.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:47:39.583 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__hyperlink-unreferenced-ta...)\""]}
{"run": "s55e", "pass": 2, "name": "hyperlink-unreferenced-targetmode-empty", "sha256": "76274697d01e3dadb522d625f2dee12ca8c010e51535f0862ea3af3b853ebb85", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00002__wfv__hyperlink-unreferenced-targetmode-empty.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 10:50:04.322 'Word found unreadable content in 00002__wfv__hyperlink-unreferenced-targetmode-empty.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 10:50:05.186 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__hyperlink-unreferenced-ta...)\""]}
{"run": "s55e", "pass": 1, "name": "s55e-control-minimal-end", "sha256": "7bd93e76bd6c60f4dd6b83c97d945addd2c4ca63b9ac36818ab5bb5fa5f48342", "observedAt": "2026-10-26T14:49:46+00:00", "staged": "00006__wfv__s55e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s55e", "pass": 2, "name": "s55e-control-minimal-end", "sha256": "7bd93e76bd6c60f4dd6b83c97d945addd2c4ca63b9ac36818ab5bb5fa5f48342", "observedAt": "2026-10-26T14:51:47+00:00", "staged": "00006__wfv__s55e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s55e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 55 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s55builder.mts`:

```ts
// Session 55 (2026-10-26): the shapes #751 and #753 ask Word about.
// - s55a (#751): a header the body references, stored as `word/header1.xml` with NO relationships part, holding a
//   `c:chart r:id`, an `o:OLEObject r:id` or a `dgm:relIds r:dm` that therefore names no relationship. Layer 161
//   hands such a part to `rels-missing-sidecar`, which the header/footer basename tolerance makes a warning, so
//   word-valid at 42600284 passes all three; at 0b26c414 `word-part-reference-relationship` rejected them. Word was
//   never shown the shape. Calibrations: the same header with its relationships part present but no `rId1`, and the
//   header with no relationships part and no `r:` reference. The `dgm:relIds` row names all four parts, as session 52
//   s52d learned the schema refuses `r:dm` alone; the image part ships only with the calibration whose sidecar names it.
// - s55b (#753): a `c:chart r:id` naming a real chart relationship whose TargetMode is spelled `Internal` or
//   `external` (OPC's ST_TargetMode is the exact enumeration Internal | External), and an empty id in one
//   relationships namespace beside the real id in the other, with the plain reference as calibration.
// - s55c (#753): session 46's word-clean-strict01 SmartArt with its diagramData relationship's TargetMode spelled
//   `Internal` or `external`, beside the unmodified package (session 52 s52d: clean).
// - s55d (calibrations for s55b and s55c): `c:chart` carrying both ids real, or only the Strict `rs:id`, separates the
//   empty id from the second relationships namespace; an unreferenced hyperlink relationship with TargetMode `external`
//   (and `External` as calibration) separates the spelling from the reference.
// - s55e (scope of the TargetMode spelling): an unreferenced hyperlink relationship with TargetMode `external` in the
//   package's `_rels/.rels` and in a referenced header's own relationships part (`External` as calibration), and the
//   spellings `External ` and `` in the main document's relationships part.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s55a pnpm exec tsx s55builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { barChartXml, CHART_CONTENT_TYPE } from "./tests/support/chart-specimens";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const RS = "http://purl.oclc.org/ooxml/officeDocument/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const DGM = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
const O = "urn:schemas-microsoft-com:office:office";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const CHART = "word/charts/chart1.xml";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "base64"),
);
const DRAWING_NS = `xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:dgm="${DGM}" xmlns:o="${O}" xmlns:r="${R}"`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, type: string, target: string, mode?: string) =>
    `<Relationship Id="${id}" Type="${type}" Target="${target}"${mode === undefined ? "" : ` TargetMode="${mode}"`}/>`;
const relsPart = (body: string) =>
    `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const withTypes = (types: string, defaults: Array<[string, string]>, overrides: Array<[string, string]>) =>
    replaceOnce(
        replaceOnce(
            types,
            '<Default Extension="rels"',
            `${defaults.map(([ext, type]) => `<Default Extension="${ext}" ContentType="${type}"/>`).join("")}<Default Extension="rels"`,
        ),
        "</Types>",
        `${overrides.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** Session 52's drawings, each in its own paragraph; `ids` is the reference's id attribute(s), verbatim. */
const chartDrawing = (ids: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart ${ids}/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const diagramDrawing = (ids: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="952500" cy="952500"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Diagram 1"/><a:graphic><a:graphicData uri="${DGM}">` +
    `<dgm:relIds ${ids}/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const oleObject = (ids: string) =>
    '<w:p><w:r><w:object><o:OLEObject Type="Embed" ProgID="Package" ShapeID="_x0000_i1025" DrawAspect="Icon" ObjectID="_1" ' +
    `${ids}/></w:object></w:r></w:p>`;
const control = () => buildDocx({ ...P });

/** A header the body references through `w:headerReference r:id="rIdH"`, stored as `word/header1.xml`, holding `body`. */
const referencedHeader = (body: string, sidecar?: string) =>
    buildDocx({
        ...P,
        ...(sidecar?.includes("media/image1.png") ? { "word/media/image1.png": PNG } : {}),
        "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}" ${DRAWING_NS}>${body}</w:hdr>`,
        ...(sidecar === undefined ? {} : { "word/_rels/header1.xml.rels": sidecar }),
        [MAIN]: replaceOnce(
            replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`),
            "<w:sectPr>",
            `<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>`,
        ),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", `${R}/header`, "header1.xml")),
        [CT]: withTypes(P[CT]!, [["png", "image/png"]], [["word/header1.xml", `${WML}.header+xml`]]),
    });

/** The minimal package, `body` before the main document's `w:sectPr` (the Strict relationships prefix `rs` declared), and a real bar chart rId9 names with `mode`. */
const chartWith = (body: string, mode?: string) =>
    buildDocx({
        ...P,
        [CHART]: barChartXml(false),
        [MAIN]: replaceOnce(
            replaceOnce(P[MAIN]!, "<w:document ", `<w:document ${DRAWING_NS} xmlns:rs="${RS}" `),
            "<w:sectPr>",
            `${body}<w:sectPr>`,
        ),
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId9", `${R}/chart`, "charts/chart1.xml", mode)),
        [CT]: withTypes(P[CT]!, [], [[CHART, CHART_CONTENT_TYPE]]),
    });

/** The minimal package with an unreferenced hyperlink relationship rId99 whose TargetMode is spelled `mode`. */
const unreferencedHyperlink = (mode: string) =>
    buildDocx({ ...P, [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId99", `${R}/hyperlink`, "https://example.com/", mode)) });

const HYPERLINK = (mode: string) => relationship("rId99", `${R}/hyperlink`, "https://example.com/", mode);
const PACKAGE_RELS = "_rels/.rels";
/** The minimal package with the unreferenced hyperlink relationship in `_rels/.rels`. */
const packageHyperlink = (mode: string) => buildDocx({ ...P, [PACKAGE_RELS]: appendRels(P[PACKAGE_RELS]!, HYPERLINK(mode)) });
/** A referenced header whose own relationships part holds only the unreferenced hyperlink relationship. */
const headerHyperlink = (mode: string) => referencedHeader("<w:p><w:r><w:t>header</w:t></w:r></w:p>", relsPart(HYPERLINK(mode)));

/** Session 46's word-clean-strict01 package with its diagramData relationship rId35's TargetMode spelled `mode`. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const DATA_REL =
    '<Relationship Id="rId35" Type="http://purl.oclc.org/ooxml/officeDocument/relationships/diagramData" Target="diagrams/data1.xml"/>';
const strict01 = async (mode?: string) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    if (mode !== undefined) {
        const rels = Buffer.from(parts[SIDECAR] as Uint8Array).toString("utf8");
        parts[SIDECAR] = replaceOnce(
            rels,
            DATA_REL,
            DATA_REL.replace('Target="diagrams/data1.xml"/>', `Target="diagrams/data1.xml" TargetMode="${mode}"/>`),
        );
    }
    return buildDocx(parts);
};

const chunks: Record<string, Array<[string, string, () => Promise<Uint8Array>]>> = {
    s55a: [
        ["s55a-control-minimal", "control", control],
        [
            "header1-nosidecar-chart",
            '#751: a referenced word/header1.xml with no relationships part holding c:chart r:id="rId1"',
            () => referencedHeader(chartDrawing('r:id="rId1"')),
        ],
        ["header1-nosidecar-oleobject", '#751: the same holding o:OLEObject r:id="rId1"', () => referencedHeader(oleObject('r:id="rId1"'))],
        [
            "header1-nosidecar-relids",
            '#751: the same holding dgm:relIds r:dm="rId1" r:lo="rId2" r:qs="rId3" r:cs="rId4" (all four, so the schema holds)',
            () => referencedHeader(diagramDrawing('r:dm="rId1" r:lo="rId2" r:qs="rId3" r:cs="rId4"')),
        ],
        [
            "header1-sidecar-no-rid1-calibration",
            '#751 calibration: the same header with c:chart r:id="rId1" and its relationships part present, holding only an image rId2',
            () => referencedHeader(chartDrawing('r:id="rId1"'), relsPart(relationship("rId2", `${R}/image`, "media/image1.png"))),
        ],
        [
            "header1-nosidecar-no-reference-calibration",
            "#751 calibration: the same header with no relationships part and no r: reference",
            () => referencedHeader("<w:p><w:r><w:t>header</w:t></w:r></w:p>"),
        ],
        ["s55a-control-minimal-end", "control", control],
    ],
    s55b: [
        ["s55b-control-minimal", "control", control],
        [
            "chart-plain-calibration",
            '#753 calibration: c:chart r:id="rId9" names a real chart relationship (no TargetMode)',
            () => chartWith(chartDrawing('r:id="rId9"')),
        ],
        [
            "chart-targetmode-internal-calibration",
            '#753 calibration: the same relationship with TargetMode="Internal"',
            () => chartWith(chartDrawing('r:id="rId9"'), "Internal"),
        ],
        [
            "chart-targetmode-lowercase-external",
            '#753: the same relationship with TargetMode="external"',
            () => chartWith(chartDrawing('r:id="rId9"'), "external"),
        ],
        [
            "chart-empty-r-id-real-rs-id",
            '#753: c:chart r:id="" rs:id="rId9" (rs: the ISO Strict relationships namespace)',
            () => chartWith(chartDrawing('r:id="" rs:id="rId9"')),
        ],
        ["chart-empty-rs-id-real-r-id", '#753: c:chart rs:id="" r:id="rId9"', () => chartWith(chartDrawing('rs:id="" r:id="rId9"'))],
        ["s55b-control-minimal-end", "control", control],
    ],
    s55c: [
        ["s55c-control-minimal", "control", control],
        ["strict01-calibration", "calibration: word-clean-strict01 unmodified (session 52 s52d: clean)", () => strict01()],
        [
            "strict01-data-targetmode-internal-calibration",
            '#753 calibration: word-clean-strict01 with diagramData rId35 TargetMode="Internal"',
            () => strict01("Internal"),
        ],
        [
            "strict01-data-targetmode-lowercase-external",
            '#753: word-clean-strict01 with diagramData rId35 TargetMode="external"',
            () => strict01("external"),
        ],
        ["s55c-control-minimal-end", "control", control],
    ],
    s55d: [
        ["s55d-control-minimal", "control", control],
        [
            "chart-both-ids-real",
            '#753 calibration: c:chart r:id="rId9" rs:id="rId9" (both relationships namespaces, both real)',
            () => chartWith(chartDrawing('r:id="rId9" rs:id="rId9"')),
        ],
        [
            "chart-rs-id-only",
            '#753 calibration: c:chart rs:id="rId9" alone in a Transitional document',
            () => chartWith(chartDrawing('rs:id="rId9"')),
        ],
        [
            "hyperlink-unreferenced-targetmode-external-calibration",
            '#753 calibration: an unreferenced hyperlink relationship with TargetMode="External"',
            () => unreferencedHyperlink("External"),
        ],
        [
            "hyperlink-unreferenced-targetmode-lowercase-external",
            '#753: an unreferenced hyperlink relationship with TargetMode="external"',
            () => unreferencedHyperlink("external"),
        ],
        ["s55d-control-minimal-end", "control", control],
    ],
    s55e: [
        ["s55e-control-minimal", "control", control],
        [
            "package-rels-hyperlink-targetmode-lowercase-external",
            '#753 scope: an unreferenced hyperlink relationship in _rels/.rels with TargetMode="external"',
            () => packageHyperlink("external"),
        ],
        [
            "package-rels-hyperlink-targetmode-external-calibration",
            '#753 scope calibration: the same with TargetMode="External"',
            () => packageHyperlink("External"),
        ],
        [
            "header-rels-hyperlink-targetmode-lowercase-external",
            '#753 scope: a referenced header\'s own relationships part holding only an unreferenced hyperlink relationship with TargetMode="external"',
            () => headerHyperlink("external"),
        ],
        [
            "header-rels-hyperlink-targetmode-external-calibration",
            '#753 scope calibration: the same with TargetMode="External"',
            () => headerHyperlink("External"),
        ],
        [
            "hyperlink-unreferenced-targetmode-external-trailing-space",
            '#753 scope: an unreferenced hyperlink relationship in the main document\'s relationships part with TargetMode="External "',
            () => unreferencedHyperlink("External "),
        ],
        ["hyperlink-unreferenced-targetmode-empty", '#753 scope: the same with TargetMode=""', () => unreferencedHyperlink("")],
        ["s55e-control-minimal-end", "control", control],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-55 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s55a", "s55b", "s55c", "s55d", "s55e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s55/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-55 parts of docs/plans/evidence/word-probes-2026-10-24.md into s55/section.md.

Reads the chunk's specimens.jsonl (validator columns at 42600284, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s55/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s55a", "s55b", "s55c", "s55d", "s55e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s55/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 55: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 42600284",
    "",
    "The shapes the review of layers 161–165 asked Word about: a header Word reads stored with no relationships part, whose "
    "references layer 161 handed to `rels-missing-sidecar` ([#751](https://github.com/jandira-tech/docx-validate/issues/751), finding 1), "
    "and a relationship whose TargetMode is spelled `external`, and a `c:chart` naming its relationship in both relationships namespaces "
    "([#753](https://github.com/jandira-tech/docx-validate/issues/753), findings 6 and 7), with s55d and s55e added after the first three "
    "chunks to separate those two shapes from their confounders and to bound the TargetMode rule. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    "is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 33 rows agree. The two times in "
    "Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A header the body references, stored as `word/header1.xml` with no relationships part, gets the recovery offer when it holds a "
    "`c:chart r:id=\"rId1\"`, an `o:OLEObject r:id=\"rId1\"`, or a `dgm:relIds` naming all four parts, as the same header does with "
    "a relationships part that lacks `rId1` (the calibration); with no `r:` reference it opens clean. Word-valid at 42600284 passes all "
    "three: false negatives.",
    "- A relationship whose TargetMode is spelled `external` gets the recovery offer whether a `c:chart` names it, it is the diagramData "
    "relationship of session 46's word-clean-strict01 SmartArt, or it is an unreferenced hyperlink relationship in the main document's "
    "relationships part; spelled `Internal` or `External` the same packages open clean. Word reads the spelling, not the reference. "
    "The unreferenced hyperlink relationship also gets the recovery offer with TargetMode `external` in the package's `_rels/.rels`, and "
    "with `External ` (trailing space) or an empty TargetMode in the main document's relationships part; with `external` in a referenced "
    "header's own relationships part it opens clean, as with `External`. Word-valid at 42600284 passes all six refused shapes: false "
    "negatives.",
    "- A `c:chart` carrying both `r:id` and the ISO Strict `rs:id` cannot be opened (open error, no recovery offer) whether one of the two "
    "is empty or both name the real chart relationship; `rs:id` alone in the Transitional document opens clean and draws the chart. "
    "Word refuses the second namespace, not the empty id. Word-valid at 42600284 passes all three: false negatives.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 42600284 | strict at 42600284 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 55</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 55 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s55builder.mts", ROOT / "s55builder.mts", "ts"), ("compare.py", ROOT / "s55/compare.py", "python"),
                         ("section.py", ROOT / "s55/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s55/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 56: 15:38Z–15:41Z on 2026-10-26, validator columns at f033a3db

The content-type shapes the #739 lane changed or left without a Word row ([#739](https://github.com/jandira-tech/docx-validate/issues/739), [#760](https://github.com/jandira-tech/docx-validate/issues/760)): `word/styles.xml` typed with the footer content type, alone and with a second footer relationship to it that no section references or that the body references; and the same part typed with an inexact spelling of the styles type, alone and with a read footer relationship to it. The chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; all 7 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- `word/styles.xml` typed `…footer+xml` gets the recovery offer reached by the main document's styles relationship alone (the session 49 class, the calibration), with a second footer relationship to it that no section references, and with that footer relationship referenced by the body. Word-valid at f033a3db rejects only the calibration: a matching footer reach exempted the styles reach's mismatch. Two false negatives, which #739's fix rejects.
- `word/styles.xml` typed `…styles+xml; charset=utf-8` gets the recovery offer alone (the calibration) and with a read footer relationship to it. Word-valid at f033a3db rejects only the calibration: the co-reach hides the inexact spelling. A false negative (#760).

| Run    | Observed             | Specimen                                | Shape                                                                                                          | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f033a3db                     | strict at f033a3db                         |
| ------ | -------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | ------------------------------------------ |
| `s56a` | 15:38:01Z, 15:41:09Z | `s56a-control-minimal`                  | control                                                                                                        | `d51807987b7778a8` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                      |
| `s56a` | 15:38:01Z, 15:41:09Z | `styles-typed-footer-calibration`       | calibration: word/styles.xml typed with the footer content type (the main document's styles relationship only) | `cb5775c6a32dd1ea` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch` |
| `s56a` | 15:38:01Z, 15:41:09Z | `styles-typed-footer-unused-footer-rel` | #739: the same plus a footer relationship no section references, also targeting word/styles.xml                | `35e261f6ac6489f3` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | valid                                      |
| `s56a` | 15:38:01Z, 15:41:09Z | `styles-typed-footer-read-footer`       | #739: the same with the body referencing that footer relationship                                              | `3cfb4d16ea623570` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | valid                                      |
| `s56a` | 15:38:01Z, 15:41:09Z | `styles-charset-calibration`            | calibration: word/styles.xml typed styles+xml; charset=utf-8 (the main document's styles relationship only)    | `969ce9b2531d1ad7` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`  | invalid: `word-part-content-type-inexact`  |
| `s56a` | 15:38:01Z, 15:41:09Z | `styles-charset-read-footer`            | #739 residue: the same plus a footer relationship the body references, targeting word/styles.xml               | `4d1a354f4d96f216` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-mismatch` |
| `s56a` | 15:38:01Z, 15:41:09Z | `s56a-control-minimal-end`              | control                                                                                                        | `d51807987b7778a8` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                      |

<details><summary>Raw records, session 56</summary>

```jsonl
{"run": "s56a", "pass": 1, "name": "s56a-control-minimal", "sha256": "d51807987b7778a80a156913945a1336c7621bda2e252511c2b39f21e32b2bd6", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00001__wfv__s56a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s56a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s56a", "pass": 2, "name": "s56a-control-minimal", "sha256": "d51807987b7778a80a156913945a1336c7621bda2e252511c2b39f21e32b2bd6", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00001__wfv__s56a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s56a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s56a", "pass": 1, "name": "styles-typed-footer-calibration", "sha256": "cb5775c6a32dd1ea4c8893d69adf2531c257e51bc811ddff3d828ba90de1c253", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00004__wfv__styles-typed-footer-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:37:52.380 'Word found unreadable content in 00004__wfv__styles-typed-footer-calibration.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:37:53.159 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-typed-footer-calib...)\""]}
{"run": "s56a", "pass": 2, "name": "styles-typed-footer-calibration", "sha256": "cb5775c6a32dd1ea4c8893d69adf2531c257e51bc811ddff3d828ba90de1c253", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00004__wfv__styles-typed-footer-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:40:20.782 'Word found unreadable content in 00004__wfv__styles-typed-footer-calibration.docx. Do you want to r … ? If you trust the source of this document, click Yes.'"]}
{"run": "s56a", "pass": 1, "name": "styles-typed-footer-unused-footer-rel", "sha256": "35e261f6ac6489f3465bdae376bac2e8ff1074ed2d6b4f4ec4a9b370fdbf404e", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00006__wfv__styles-typed-footer-unused-footer-rel.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:38:00.760 'Word found unreadable content in 00006__wfv__styles-typed-footer-unused-footer-rel.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:38:01.576 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-typed-footer-unuse...)\""]}
{"run": "s56a", "pass": 2, "name": "styles-typed-footer-unused-footer-rel", "sha256": "35e261f6ac6489f3465bdae376bac2e8ff1074ed2d6b4f4ec4a9b370fdbf404e", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00006__wfv__styles-typed-footer-unused-footer-rel.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:41:08.849 Microsoft Word, Word found unreadable content in 00006__wfv__styles-typed-footer-unused-footer-rel.d … t? If you trust the source of this document, click Yes."]}
{"run": "s56a", "pass": 1, "name": "styles-typed-footer-read-footer", "sha256": "3cfb4d16ea62357053a411b7160855d357e7a0af40a7e5379cbf95782dad2788", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00005__wfv__styles-typed-footer-read-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:37:56.557 'Word found unreadable content in 00005__wfv__styles-typed-footer-read-footer.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:37:57.376 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-typed-footer-read-...)\""]}
{"run": "s56a", "pass": 2, "name": "styles-typed-footer-read-footer", "sha256": "3cfb4d16ea62357053a411b7160855d357e7a0af40a7e5379cbf95782dad2788", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00005__wfv__styles-typed-footer-read-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:40:25.327 \"Word found unreadable content in 00005__wfv__styles-typed-footer-read-footer.docx. Do you want to r … ? If you trust the source of this document, click Yes.\"", "2026-10-26 11:40:25.328 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-typed-footer-read-...)\""]}
{"run": "s56a", "pass": 1, "name": "styles-charset-calibration", "sha256": "969ce9b2531d1ad7150e3edf2e0e376a932b5d05003d1bd7f5b3c1dfa91007bb", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00002__wfv__styles-charset-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:36:35.189 'Word found unreadable content in 00002__wfv__styles-charset-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:36:40.955 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-charset-calibratio...)\""]}
{"run": "s56a", "pass": 2, "name": "styles-charset-calibration", "sha256": "969ce9b2531d1ad7150e3edf2e0e376a932b5d05003d1bd7f5b3c1dfa91007bb", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00002__wfv__styles-charset-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:38:18.895 'Word found unreadable content in 00002__wfv__styles-charset-calibration.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:38:19.783 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-charset-calibratio...)\""]}
{"run": "s56a", "pass": 1, "name": "styles-charset-read-footer", "sha256": "4d1a354f4d96f216d52d8f58ff87dba080ab86bb240624104d193878d8f4c02f", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00003__wfv__styles-charset-read-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:37:35.520 Microsoft Word, Word found unreadable content in 00003__wfv__styles-charset-read-footer.docx. Do you … t? If you trust the source of this document, click Yes.", "2026-10-26 11:37:48.659 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-charset-read-foote...)\""]}
{"run": "s56a", "pass": 2, "name": "styles-charset-read-footer", "sha256": "4d1a354f4d96f216d52d8f58ff87dba080ab86bb240624104d193878d8f4c02f", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00003__wfv__styles-charset-read-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 11:39:07.329 'Word found unreadable content in 00003__wfv__styles-charset-read-footer.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 11:39:07.892 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-charset-read-foote...)\""]}
{"run": "s56a", "pass": 1, "name": "s56a-control-minimal-end", "sha256": "d51807987b7778a80a156913945a1336c7621bda2e252511c2b39f21e32b2bd6", "observedAt": "2026-10-26T15:38:01+00:00", "staged": "00000__wfv__s56a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s56a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s56a", "pass": 2, "name": "s56a-control-minimal-end", "sha256": "d51807987b7778a80a156913945a1336c7621bda2e252511c2b39f21e32b2bd6", "observedAt": "2026-10-26T15:41:09+00:00", "staged": "00000__wfv__s56a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s56a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 56 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s56builder.mts`:

```ts
// Session 56 (2026-10-26): the content-type shapes lane F (#739) changed or left without a Word row.
// - s56a: word/styles.xml typed with the footer content type, alone (calibration), with a footer relationship the body
//   never references (no w:footerReference) also targeting it, and with a footer relationship the body references.
//   #739's fix stops a matching footer reach from exempting the styles reach's mismatch, so word-valid now rejects the
//   unused-footer row; Word was never shown it. Then word/styles.xml typed with an inexact spelling of the styles type
//   (`; charset=utf-8`) alone, and with a read footer relationship targeting it: lane F reports word-valid passes the
//   co-reach row, which no session showed.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s56a pnpm exec tsx s56builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN_TYPE = `${WML}.document.main+xml`;
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

type Kind = "numbering" | "settings" | "fontTable";
/** The relationship segment, the part body and the content type of each kind (the bodies session 47 used). */
const KINDS: Record<Kind, { root: string; ct: string }> = {
    numbering: { root: `${XML_DECL}<w:numbering xmlns:w="${W}"/>`, ct: `${WML}.numbering+xml` },
    settings: { root: `${XML_DECL}<w:settings xmlns:w="${W}"/>`, ct: `${WML}.settings+xml` },
    fontTable: { root: `${XML_DECL}<w:fonts xmlns:w="${W}"/>`, ct: `${WML}.fontTable+xml` },
};
/** The other mapped Word content types the rows type a part with. */
const TYPES = {
    main: MAIN_TYPE,
    styles: STYLES_TYPE,
    theme: "application/vnd.openxmlformats-officedocument.theme+xml",
    glossary: `${WML}.document.glossary+xml`,
    header: `${WML}.header+xml`,
    footer: `${WML}.footer+xml`,
    footnotes: `${WML}.footnotes+xml`,
    endnotes: `${WML}.endnotes+xml`,
    comments: `${WML}.comments+xml`,
    settings: KINDS.settings.ct,
    fontTable: KINDS.fontTable.ct,
    numbering: KINDS.numbering.ct,
};
const SPELLINGS: Array<[string, string]> = [
    ["octet-upper", "APPLICATION/OCTET-STREAM"],
    ["octet-charset", "application/octet-stream; charset=utf-8"],
    ["image-png", "image/png"],
    ["foo-xml", "application/foo+xml"],
];

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${REL}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const retype = (ct: string, part: string, own: string, type: string) =>
    replaceOnce(ct, `<Override PartName="/${part}" ContentType="${own}"/>`, `<Override PartName="/${part}" ContentType="${type}"/>`);
const control = () => buildDocx({ ...P });

/** The minimal package plus `word/<kind>.xml` related from the main document's sidecar as rId2, typed `type`. */
const withRelated = (kind: Kind, type = KINDS[kind].ct): Record<string, string> => ({
    ...P,
    [`word/${kind}.xml`]: KINDS[kind].root,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", kind, `${kind}.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}.xml`, type]),
});
const relatedTyped = (kind: Kind, type: string) => buildDocx(withRelated(kind, type));
const mainTyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, "word/document.xml", MAIN_TYPE, type) });
const stylesTyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) });

/** `parts` plus a footer relationship (rIdF) to `target` (relative to word/) that the body's section references. */
const withReadFooter = (parts: Record<string, string>, target: string): Record<string, string> => ({
    ...parts,
    "word/document.xml": replaceOnce(
        replaceOnce(parts["word/document.xml"]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${REL}"`),
        "<w:sectPr>",
        `<w:sectPr><w:footerReference w:type="default" r:id="rIdF"/>`,
    ),
    [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", target)),
});
const mainFooterCoReach = (type: string) =>
    buildDocx(withReadFooter({ ...P, [CT]: retype(P[CT]!, "word/document.xml", MAIN_TYPE, type) }, "document.xml"));
const numberingFooterCoReach = (type: string) => buildDocx(withReadFooter(withRelated("numbering", type), "numbering.xml"));
const stylesFooterCoReach = (type: string) =>
    buildDocx(withReadFooter({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) }, "styles.xml"));
/** `parts` plus a footer relationship (rIdF) to `target` (relative to word/) that no section references. */
const withUnusedFooter = (parts: Record<string, string>, target: string): Record<string, string> => ({
    ...parts,
    [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", target)),
});
const stylesRetyped = (type: string): Record<string, string> => ({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) });
const STYLES_CHARSET = `${STYLES_TYPE}; charset=utf-8`;
type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s56a: withControls("s56a", [
        [
            "styles-typed-footer-calibration",
            "calibration: word/styles.xml typed with the footer content type (the main document's styles relationship only)",
            () => buildDocx(stylesRetyped(TYPES.footer)),
        ],
        [
            "styles-typed-footer-unused-footer-rel",
            "#739: the same plus a footer relationship no section references, also targeting word/styles.xml",
            () => buildDocx(withUnusedFooter(stylesRetyped(TYPES.footer), "styles.xml")),
        ],
        [
            "styles-typed-footer-read-footer",
            "#739: the same with the body referencing that footer relationship",
            () => buildDocx(withReadFooter(stylesRetyped(TYPES.footer), "styles.xml")),
        ],
        [
            "styles-charset-calibration",
            "calibration: word/styles.xml typed styles+xml; charset=utf-8 (the main document's styles relationship only)",
            () => buildDocx(stylesRetyped(STYLES_CHARSET)),
        ],
        [
            "styles-charset-read-footer",
            "#739 residue: the same plus a footer relationship the body references, targeting word/styles.xml",
            () => buildDocx(withReadFooter(stylesRetyped(STYLES_CHARSET), "styles.xml")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-56 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s56a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s56/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-56 parts of docs/plans/evidence/word-probes-2026-10-24.md into s56/section.md.

Reads the chunk's specimens.jsonl (validator columns at f033a3db, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s56/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s56a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s56/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 56: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at f033a3db",
    "",
    "The content-type shapes the #739 lane changed or left without a Word row "
    "([#739](https://github.com/jandira-tech/docx-validate/issues/739), "
    "[#760](https://github.com/jandira-tech/docx-validate/issues/760)): `word/styles.xml` typed with the footer content type, "
    "alone and with a second footer relationship to it that no section references or that the body references; and the same part "
    "typed with an inexact spelling of the styles type, alone and with a read footer relationship to it. The chunk ran twice, as two "
    "separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and "
    "`unknown` otherwise; all 7 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    "builder's description of the specimen.",
    "",
    "- `word/styles.xml` typed `…footer+xml` gets the recovery offer reached by the main document's styles relationship alone (the "
    "session 49 class, the calibration), with a second footer relationship to it that no section references, and with that footer "
    "relationship referenced by the body. Word-valid at f033a3db rejects only the calibration: a matching footer reach exempted the "
    "styles reach's mismatch. Two false negatives, which #739's fix rejects.",
    "- `word/styles.xml` typed `…styles+xml; charset=utf-8` gets the recovery offer alone (the calibration) and with a read footer "
    "relationship to it. Word-valid at f033a3db rejects only the calibration: the co-reach hides the inexact spelling. A false "
    "negative (#760).",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at f033a3db | strict at f033a3db |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 56</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 56 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s56builder.mts", ROOT / "s56builder.mts", "ts"), ("compare.py", ROOT / "s56/compare.py", "python"),
                         ("section.py", ROOT / "s56/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s56/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records")
`````

</details>

### Session 57: 17:08Z–17:33Z on 2026-10-26, validator columns at d93138a9

The shapes the adversarial reviews of layers 168–179 found without a Word row ([#775](https://github.com/jandira-tech/docx-validate/issues/775)–[#779](https://github.com/jandira-tech/docx-validate/issues/779)). Seven chunks, each opening and closing with the minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 56 of 56 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- #779: each of the 13 mapped-type pairs no session had shown gets the recovery offer. These are the main document typed webSettings; `word/settings.xml` typed webSettings, glossary, footer, footnotes or endnotes; `word/numbering.xml` typed webSettings, glossary, theme or footer; and `word/styles.xml` typed webSettings, glossary or footnotes. Word-valid at d93138a9 already rejects all 13; these rows are the observation its recovery sentences lacked.
- #778: a `word/footer1.xml` the body references gets the recovery offer typed with the styles, main document, numbering or settings content type; word-valid rejects the first three and accepts the settings row. A `word/header1.xml` the body references gets the recovery offer typed with the main document or styles content type; word-valid accepts both. A reached glossary's own styles part that a footer relationship the body references also reaches gets the recovery offer; word-valid rejects it. Three false negatives.
- #777: the refused attached-toolbar fixture with `word/customizations.xml` renamed without an extension, or to `word/customizations.bin` (its Override keeping the keyMapCustomizations type), still gets the recovery offer; the same renames of the repaired fixture open clean. Word-valid accepts both refused rows. Two false negatives.
- #776: `word/styles.xml` typed `…styles+xml; charset=utf-8` and also the target of a header, comments, footnotes or endnotes relationship the body reads gets the recovery offer, and word-valid rejects all four. The calibrations with the exact styles type get the recovery offer too, so the refusal does not need the inexact spelling; word-valid rejects only the footnotes calibration. Three false negatives. The comments, footnotes and endnotes specimens reference an id (`w:commentReference w:id="0"`, `w:footnoteReference w:id="1"`, `w:endnoteReference w:id="1"`) in a part rooted `w:styles`, so a dangling reference is a possible confound in those three; the header rows have no such reference.
- #775: a reached glossary whose relationships part holds an unreferenced hyperlink relationship with `TargetMode="external"` gets the recovery offer; with `External` it opens clean. Word-valid accepts the lowercase row: a false negative. A used `word/footnotes.xml`, a used `word/comments.xml`, a reached glossary and the main document, each with no relationships part and holding `c:chart r:id="rId1"`, get the recovery offer, and word-valid rejects all four; their text-only calibrations open clean.

| Run    | Observed             | Specimen                                                  | Shape                                                                                                                                                          | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at d93138a9                                                       | strict at d93138a9                                                                                                                                                                       |
| ------ | -------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s57a` | 17:08:33Z, 17:11:57Z | `s57a-control-minimal`                                    | control                                                                                                                                                        | `248994cb3ba586ab` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57a` | 17:08:33Z, 17:11:57Z | `main-typed-websettings`                                  | #779: the main document typed by its Override with the webSettings content type                                                                                | `1dd63b0362a9e5ae` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `settings-typed-websettings`                              | #779: the related word/settings.xml typed by its Override with the webSettings content type                                                                    | `a07bccc4df50aec5` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `settings-typed-glossary`                                 | #779: the related word/settings.xml typed by its Override with the glossary content type                                                                       | `0c35b73b70acf725` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `settings-typed-footer`                                   | #779: the related word/settings.xml typed by its Override with the footer content type                                                                         | `300205b0c5d2f7ad` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `settings-typed-footnotes`                                | #779: the related word/settings.xml typed by its Override with the footnotes content type                                                                      | `287012fa6161653f` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `settings-typed-endnotes`                                 | #779: the related word/settings.xml typed by its Override with the endnotes content type                                                                       | `75d5b977aa0bb360` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57a` | 17:08:33Z, 17:11:57Z | `s57a-control-minimal-end`                                | control                                                                                                                                                        | `4c614976bbf43096` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57b` | 17:15:45Z, 17:17:08Z | `s57b-control-minimal`                                    | control                                                                                                                                                        | `4c614976bbf43096` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57b` | 17:15:45Z, 17:17:08Z | `numbering-typed-websettings`                             | #779: the related word/numbering.xml typed by its Override with the webSettings content type                                                                   | `9feccf6245e5729b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `numbering-typed-glossary`                                | #779: the related word/numbering.xml typed by its Override with the glossary content type                                                                      | `1a37fb98665b32c3` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `numbering-typed-theme`                                   | #779: the related word/numbering.xml typed by its Override with the theme content type                                                                         | `878fa3963393bc00` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `numbering-typed-footer`                                  | #779: the related word/numbering.xml typed by its Override with the footer content type                                                                        | `5a0759077ea381c8` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `styles-typed-websettings`                                | #779: the word/styles.xml typed by its Override with the webSettings content type                                                                              | `e8219ecc3698979d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `styles-typed-glossary`                                   | #779: the word/styles.xml typed by its Override with the glossary content type                                                                                 | `1b7a969bdf64d566` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57b` | 17:15:45Z, 17:17:08Z | `s57b-control-minimal-end`                                | control                                                                                                                                                        | `9b2df8d2561ad86a` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57c` | 17:20:06Z, 17:23:25Z | `s57c-control-minimal`                                    | control                                                                                                                                                        | `609cbac70075969a` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57c` | 17:20:06Z, 17:23:25Z | `styles-typed-footnotes`                                  | #779: the word/styles.xml typed by its Override with the footnotes content type                                                                                | `617637d2915468c7` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57c` | 17:20:06Z, 17:23:25Z | `footer1-referenced-typed-styles`                         | #778: a word/footer1.xml the body references, typed by its Override with the styles content type                                                               | `c1e11e67de461ed7` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57c` | 17:20:06Z, 17:23:25Z | `footer1-referenced-typed-main`                           | #778: the same footer typed with the main document content type                                                                                                | `a844faa237b4cf11` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57c` | 17:20:06Z, 17:23:25Z | `footer1-referenced-typed-numbering`                      | #778: the same footer typed with the numbering content type                                                                                                    | `0b5913f49e90938b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57c` | 17:20:06Z, 17:23:25Z | `footer1-referenced-typed-settings`                       | #778: the same footer typed with the settings content type                                                                                                     | `b0d85ca51f8e5701` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57c` | 17:20:06Z, 17:23:25Z | `header1-referenced-typed-main`                           | #778: a word/header1.xml the body references, typed with the main document content type                                                                        | `7e26835eb7150098` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57c` | 17:20:06Z, 17:23:25Z | `s57c-control-minimal-end`                                | control                                                                                                                                                        | `0c73b5b2075522cb` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57d` | 17:25:13Z, 17:27:17Z | `s57d-control-minimal`                                    | control                                                                                                                                                        | `0c73b5b2075522cb` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57d` | 17:25:13Z, 17:27:17Z | `header1-referenced-typed-styles`                         | #778: the same header typed with the styles content type                                                                                                       | `158e1abfd05cea58` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57d` | 17:25:13Z, 17:27:17Z | `glossary-styles-main-footer-coreach`                     | #778: a reached glossary's own word/glossary/styles.xml (styles type, related by its sidecar) that a footer relationship the main body references also targets | `3727640958988634` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch`                                   | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                                                                                                     |
| `s57d` | 17:25:13Z, 17:27:17Z | `customizations-noext-refused`                            | #777: the refused toolbar fixture with word/customizations.xml renamed word/customizations (no extension), relationship, sidecar and Override renamed with it  | `1163f74dd346f646` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s57d` | 17:25:13Z, 17:27:17Z | `customizations-noext-repaired-calibration`               | #777 calibration: the same rename of the repaired toolbar fixture                                                                                              | `d78e36f247b7e0b3` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s57d` | 17:25:13Z, 17:27:17Z | `customizations-bin-refused`                              | #777: the refused toolbar fixture with word/customizations.xml renamed word/customizations.bin (its Override keeps the keyMapCustomizations type)              | `2d6ad179d337d957` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s57d` | 17:25:13Z, 17:27:17Z | `customizations-bin-repaired-calibration`                 | #777 calibration: the same .bin rename of the repaired toolbar fixture                                                                                         | `54425e5a751ebfd6` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `rels-unreferenced`, `rels-unreferenced`, `paraid-missing-element`, `style-default-missing`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error` |
| `s57d` | 17:25:13Z, 17:27:17Z | `s57d-control-minimal-end`                                | control                                                                                                                                                        | `4ebc5fc7a77793b4` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57e` | 17:28:05Z, 17:28:33Z | `s57e-control-minimal`                                    | control                                                                                                                                                        | `0aa8dce5d97ed390` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-charset-read-header`                              | #776: word/styles.xml typed styles+xml; charset=utf-8, also the target of a header relationship the body references                                            | `35526b2da46eb9aa` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`                                    | invalid: `word-part-content-type-inexact`, `word-part-content-type-mismatch`                                                                                                             |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-charset-read-comments`                            | #776: the same with a comments relationship and a w:commentReference w:id="0" in the body                                                                      | `242becce0a9acfd3` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`                                    | invalid: `word-part-content-type-inexact`, `word-part-content-type-mismatch`, `comment-marker-missing`, `comment-thread-count-mismatch`                                                  |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-charset-read-footnotes`                           | #776: the same with a footnotes relationship and a w:footnoteReference w:id="1" in the body                                                                    | `830bef6fe25e6346` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`, `word-footnote-reference-missing` | invalid: `word-part-content-type-inexact`, `word-part-content-type-mismatch`, `word-footnote-reference-missing`                                                                          |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-charset-read-endnotes`                            | #776: the same with an endnotes relationship and a w:endnoteReference w:id="1" in the body                                                                     | `f9f60f2fb8997592` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`                                    | invalid: `word-part-content-type-inexact`, `word-part-content-type-mismatch`                                                                                                             |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-exact-read-header-calibration`                    | #776 calibration: the header co-reach with the exact styles content type                                                                                       | `7cd14ebc0aa7f84a` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57e` | 17:28:05Z, 17:28:33Z | `styles-exact-read-comments-calibration`                  | #776 calibration: the comments co-reach with the exact styles content type                                                                                     | `21a2c19651d13d9a` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`, `comment-marker-missing`, `comment-thread-count-mismatch`                                                                                    |
| `s57e` | 17:28:05Z, 17:28:33Z | `s57e-control-minimal-end`                                | control                                                                                                                                                        | `da7e7c5a27003b23` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57f` | 17:29:26Z, 17:31:55Z | `s57f-control-minimal`                                    | control                                                                                                                                                        | `da7e7c5a27003b23` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57f` | 17:29:26Z, 17:31:55Z | `styles-exact-read-footnotes-calibration`                 | #776 calibration: the footnotes co-reach with the exact styles content type                                                                                    | `a0e211c406472b63` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing`                                   | invalid: `word-part-content-type-mismatch`, `word-footnote-reference-missing`                                                                                                            |
| `s57f` | 17:29:26Z, 17:31:55Z | `styles-exact-read-endnotes-calibration`                  | #776 calibration: the endnotes co-reach with the exact styles content type                                                                                     | `66ca502ed802554c` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `word-part-content-type-mismatch`                                                                                                                                               |
| `s57f` | 17:29:26Z, 17:31:55Z | `glossary-rels-hyperlink-targetmode-lowercase-external`   | #775: a reached glossary whose relationships part holds an unreferenced hyperlink relationship with TargetMode="external"                                      | `1ac1e13540f1e6a8` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                        | invalid: `paraid-missing-element`, `xsd-summary`, `xsd-error`                                                                                                                            |
| `s57f` | 17:29:26Z, 17:31:55Z | `glossary-rels-hyperlink-targetmode-external-calibration` | #775 calibration: the same with TargetMode="External"                                                                                                          | `3078096a815ba072` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `paraid-missing-element`                                                                                                                                                        |
| `s57f` | 17:29:26Z, 17:31:55Z | `footnotes-nosidecar-chart`                               | #775: a used word/footnotes.xml with no relationships part, footnote 1 holding c:chart r:id="rId1"                                                             | `f5fe300bcbdc13e8` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`, `word-part-reference-relationship`          | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `word-part-reference-relationship`                                                                                            |
| `s57f` | 17:29:26Z, 17:31:55Z | `comments-nosidecar-chart`                                | #775: a used word/comments.xml with no relationships part, comment 0 holding c:chart r:id="rId1"                                                               | `48607444445ed090` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`, `word-part-reference-relationship`          | invalid: `rels-missing-sidecar`, `comment-thread-count-mismatch`, `paraid-missing-element`, `word-part-reference-relationship`                                                           |
| `s57f` | 17:29:26Z, 17:31:55Z | `s57f-control-minimal-end`                                | control                                                                                                                                                        | `97d90bf4ec540dde` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57g` | 17:32:36Z, 17:33:07Z | `s57g-control-minimal`                                    | control                                                                                                                                                        | `18228f0990d5c723` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |
| `s57g` | 17:32:36Z, 17:33:07Z | `glossary-nosidecar-chart`                                | #775: a reached glossary document with no relationships part holding c:chart r:id="rId1"                                                                       | `fab66d767d81f3a0` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`, `word-part-reference-relationship`          | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `word-part-reference-relationship`                                                                                            |
| `s57g` | 17:32:36Z, 17:33:07Z | `main-nosidecar-chart`                                    | #775: the main document with no relationships part holding c:chart r:id="rId1"                                                                                 | `87dced31c409fcd2` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar`, `word-part-reference-relationship`          | invalid: `rels-unreferenced`, `rels-missing-sidecar`, `paraid-missing-element`, `word-part-reference-relationship`                                                                       |
| `s57g` | 17:32:36Z, 17:33:07Z | `footnotes-nosidecar-text-calibration`                    | #775 calibration: the used footnotes part with no relationships part, footnote 1 holding text only                                                             | `da8dc994cfa8023f` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `paraid-missing-element`                                                                                                                                                        |
| `s57g` | 17:32:36Z, 17:33:07Z | `comments-nosidecar-text-calibration`                     | #775 calibration: the used comments part with no relationships part, comment 0 holding text only                                                               | `2fa3493ecd11ea2e` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                                                                                                       |
| `s57g` | 17:32:36Z, 17:33:07Z | `glossary-nosidecar-text-calibration`                     | #775 calibration: the reached glossary with no relationships part, text only                                                                                   | `3fd0cd4bd5266aee` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `paraid-missing-element`                                                                                                                                                        |
| `s57g` | 17:32:36Z, 17:33:07Z | `main-nosidecar-text-calibration`                         | #775 calibration: the main document with no relationships part, text only                                                                                      | `bceea61fadc5f8c0` | clean-open     | clean-open     | clean-open                 | valid                                                                        | invalid: `rels-unreferenced`, `paraid-missing-element`                                                                                                                                   |
| `s57g` | 17:32:36Z, 17:33:07Z | `s57g-control-minimal-end`                                | control                                                                                                                                                        | `758215b976d8e376` | clean-open     | clean-open     | clean-open                 | valid                                                                        | valid                                                                                                                                                                                    |

<details><summary>Raw records, session 57</summary>

```jsonl
{"run": "s57a", "pass": 1, "name": "s57a-control-minimal", "sha256": "248994cb3ba586ab0a5f937cc8d49c1846ba177834e44e205d3c7a3116e0b15d", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00002__wfv__s57a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57a", "pass": 2, "name": "s57a-control-minimal", "sha256": "248994cb3ba586ab0a5f937cc8d49c1846ba177834e44e205d3c7a3116e0b15d", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00002__wfv__s57a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57a", "pass": 1, "name": "main-typed-websettings", "sha256": "1dd63b0362a9e5aee5b1621781958dd1cb0869fa85b80377b6893d0882c67531", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00000__wfv__main-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:04:42.033 'Word found unreadable content in 00000__wfv__main-typed-websettings.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:04:42.642 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00000__wfv__main-typed-websettings.docx)\""]}
{"run": "s57a", "pass": 2, "name": "main-typed-websettings", "sha256": "1dd63b0362a9e5aee5b1621781958dd1cb0869fa85b80377b6893d0882c67531", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00000__wfv__main-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:09:34.127 'Word found unreadable content in 00000__wfv__main-typed-websettings.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:09:34.731 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00000__wfv__main-typed-websettings.docx)\""]}
{"run": "s57a", "pass": 1, "name": "settings-typed-websettings", "sha256": "a07bccc4df50aec51433cb27a9d1caf4e2cc7ec8476f31d930af37c902095e51", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00007__wfv__settings-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:08:32.611 'Word found unreadable content in 00007__wfv__settings-typed-websettings.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:08:33.395 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__settings-typed-websetting...)\""]}
{"run": "s57a", "pass": 2, "name": "settings-typed-websettings", "sha256": "a07bccc4df50aec51433cb27a9d1caf4e2cc7ec8476f31d930af37c902095e51", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00007__wfv__settings-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:11:57.468 Microsoft Word, Word found unreadable content in 00007__wfv__settings-typed-websettings.docx. Do you … t? If you trust the source of this document, click Yes.", "2026-10-26 13:11:57.623 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00007__wfv__settings-typed-websetting...)'"]}
{"run": "s57a", "pass": 1, "name": "settings-typed-glossary", "sha256": "0c35b73b70acf725b800e5ef5b518689e8130472c9e20d72796e71b0c8f94f05", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00006__wfv__settings-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:08:26.377 'Word found unreadable content in 00006__wfv__settings-typed-glossary.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:08:27.390 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-typed-glossary.docx)\""]}
{"run": "s57a", "pass": 2, "name": "settings-typed-glossary", "sha256": "0c35b73b70acf725b800e5ef5b518689e8130472c9e20d72796e71b0c8f94f05", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00006__wfv__settings-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:11:14.031 \"Word found unreadable content in 00006__wfv__settings-typed-glossary.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:11:14.032 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__settings-typed-glossary.docx)\""]}
{"run": "s57a", "pass": 1, "name": "settings-typed-footer", "sha256": "300205b0c5d2f7ad5c8f66e13455c4b1b54d65751993da51fa5229dc7407992a", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00004__wfv__settings-typed-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:08:09.811 'Word found unreadable content in 00004__wfv__settings-typed-footer.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'"]}
{"run": "s57a", "pass": 2, "name": "settings-typed-footer", "sha256": "300205b0c5d2f7ad5c8f66e13455c4b1b54d65751993da51fa5229dc7407992a", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00004__wfv__settings-typed-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:10:35.415 Microsoft Word, Word found unreadable content in 00004__wfv__settings-typed-footer.docx. Do you want … t? If you trust the source of this document, click Yes.", "2026-10-26 13:10:35.543 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … y converter.\\n(00004__wfv__settings-typed-footer.docx)'"]}
{"run": "s57a", "pass": 1, "name": "settings-typed-footnotes", "sha256": "287012fa6161653f0237327f36d1194fda343b4526a951783e95d8ebe3cb0633", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00005__wfv__settings-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:08:18.762 \"Word found unreadable content in 00005__wfv__settings-typed-footnotes.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:08:18.762 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__settings-typed-footnotes....)\""]}
{"run": "s57a", "pass": 2, "name": "settings-typed-footnotes", "sha256": "287012fa6161653f0237327f36d1194fda343b4526a951783e95d8ebe3cb0633", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00005__wfv__settings-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:11:11.078 'Word found unreadable content in 00005__wfv__settings-typed-footnotes.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s57a", "pass": 1, "name": "settings-typed-endnotes", "sha256": "75d5b977aa0bb360f1554dd686c31654ab9786edd36d4691df259b80f5dde9df", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00003__wfv__settings-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:05:12.511 \"Word found unreadable content in 00003__wfv__settings-typed-endnotes.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57a", "pass": 2, "name": "settings-typed-endnotes", "sha256": "75d5b977aa0bb360f1554dd686c31654ab9786edd36d4691df259b80f5dde9df", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00003__wfv__settings-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:09:51.653 \"Word found unreadable content in 00003__wfv__settings-typed-endnotes.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57a", "pass": 1, "name": "s57a-control-minimal-end", "sha256": "4c614976bbf43096fa3eec605cffc55e37c819d707da95359838e3e1606b28ea", "observedAt": "2026-10-26T17:08:33+00:00", "staged": "00001__wfv__s57a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57a", "pass": 2, "name": "s57a-control-minimal-end", "sha256": "4c614976bbf43096fa3eec605cffc55e37c819d707da95359838e3e1606b28ea", "observedAt": "2026-10-26T17:11:57+00:00", "staged": "00001__wfv__s57a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57b", "pass": 1, "name": "s57b-control-minimal", "sha256": "4c614976bbf43096fa3eec605cffc55e37c819d707da95359838e3e1606b28ea", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00005__wfv__s57b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57b", "pass": 2, "name": "s57b-control-minimal", "sha256": "4c614976bbf43096fa3eec605cffc55e37c819d707da95359838e3e1606b28ea", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00005__wfv__s57b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57b", "pass": 1, "name": "numbering-typed-websettings", "sha256": "9feccf6245e5729b40617aaa36bfc5a76e3ff2c6ba769be92eb55f4afe166736", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00003__wfv__numbering-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:14:54.957 Microsoft Word, Word found unreadable content in 00003__wfv__numbering-typed-websettings.docx. Do yo … t? If you trust the source of this document, click Yes."]}
{"run": "s57b", "pass": 2, "name": "numbering-typed-websettings", "sha256": "9feccf6245e5729b40617aaa36bfc5a76e3ff2c6ba769be92eb55f4afe166736", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00003__wfv__numbering-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:16:58.665 'Word found unreadable content in 00003__wfv__numbering-typed-websettings.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:16:59.186 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__numbering-typed-websettin...)\""]}
{"run": "s57b", "pass": 1, "name": "numbering-typed-glossary", "sha256": "1a37fb98665b32c38b4bd9e52c9d30c5094158cbd9bfbaea8c4441950e8f380e", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00001__wfv__numbering-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:13:21.281 Microsoft Word, Word found unreadable content in 00001__wfv__numbering-typed-glossary.docx. Do you w … t? If you trust the source of this document, click Yes."]}
{"run": "s57b", "pass": 2, "name": "numbering-typed-glossary", "sha256": "1a37fb98665b32c38b4bd9e52c9d30c5094158cbd9bfbaea8c4441950e8f380e", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00001__wfv__numbering-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:16:50.244 Microsoft Word, Word found unreadable content in 00001__wfv__numbering-typed-glossary.docx. Do you w … t? If you trust the source of this document, click Yes."]}
{"run": "s57b", "pass": 1, "name": "numbering-typed-theme", "sha256": "878fa3963393bc007b295810c9fd1f3a4f9b77cd9b41794bae7c610606f51af2", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00002__wfv__numbering-typed-theme.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:14:09.859 Microsoft Word, Word found unreadable content in 00002__wfv__numbering-typed-theme.docx. Do you want … t? If you trust the source of this document, click Yes.", "2026-10-26 13:14:10.552 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__numbering-typed-theme.docx)\""]}
{"run": "s57b", "pass": 2, "name": "numbering-typed-theme", "sha256": "878fa3963393bc007b295810c9fd1f3a4f9b77cd9b41794bae7c610606f51af2", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00002__wfv__numbering-typed-theme.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:16:54.463 'Word found unreadable content in 00002__wfv__numbering-typed-theme.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:16:54.970 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__numbering-typed-theme.docx)\""]}
{"run": "s57b", "pass": 1, "name": "numbering-typed-footer", "sha256": "5a0759077ea381c881c240af287e289259f29d90f481fda17dd498f1af5ebf59", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00000__wfv__numbering-typed-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:12:28.530 'Word found unreadable content in 00000__wfv__numbering-typed-footer.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:12:29.070 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00000__wfv__numbering-typed-footer.docx)\""]}
{"run": "s57b", "pass": 2, "name": "numbering-typed-footer", "sha256": "5a0759077ea381c881c240af287e289259f29d90f481fda17dd498f1af5ebf59", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00000__wfv__numbering-typed-footer.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:15:55.962 'Word found unreadable content in 00000__wfv__numbering-typed-footer.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:15:56.484 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00000__wfv__numbering-typed-footer.docx)\""]}
{"run": "s57b", "pass": 1, "name": "styles-typed-websettings", "sha256": "e8219ecc3698979d23a0fdab2c65e4ebb6015fcbfe9d74bc75f4dbce0d972c99", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00007__wfv__styles-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:15:45.068 Microsoft Word, Word found unreadable content in 00007__wfv__styles-typed-websettings.docx. Do you w … t? If you trust the source of this document, click Yes.", "2026-10-26 13:15:45.180 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00007__wfv__styles-typed-websettings....)'"]}
{"run": "s57b", "pass": 2, "name": "styles-typed-websettings", "sha256": "e8219ecc3698979d23a0fdab2c65e4ebb6015fcbfe9d74bc75f4dbce0d972c99", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00007__wfv__styles-typed-websettings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:17:07.430 'Word found unreadable content in 00007__wfv__styles-typed-websettings.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:17:08.231 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-typed-websettings....)\""]}
{"run": "s57b", "pass": 1, "name": "styles-typed-glossary", "sha256": "1b7a969bdf64d5666e74ebcf1d42d665cc0d4d04cdb66e176986e9c2619a26f6", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00006__wfv__styles-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:15:01.375 \"Word found unreadable content in 00006__wfv__styles-typed-glossary.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:15:01.376 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__styles-typed-glossary.docx)\""]}
{"run": "s57b", "pass": 2, "name": "styles-typed-glossary", "sha256": "1b7a969bdf64d5666e74ebcf1d42d665cc0d4d04cdb66e176986e9c2619a26f6", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00006__wfv__styles-typed-glossary.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:17:03.246 'Word found unreadable content in 00006__wfv__styles-typed-glossary.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:17:04.158 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__styles-typed-glossary.docx)\""]}
{"run": "s57b", "pass": 1, "name": "s57b-control-minimal-end", "sha256": "9b2df8d2561ad86a7df2f7bd0327d366e0aa347192b99a3349b9d37853fec2eb", "observedAt": "2026-10-26T17:15:45+00:00", "staged": "00004__wfv__s57b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57b", "pass": 2, "name": "s57b-control-minimal-end", "sha256": "9b2df8d2561ad86a7df2f7bd0327d366e0aa347192b99a3349b9d37853fec2eb", "observedAt": "2026-10-26T17:17:08+00:00", "staged": "00004__wfv__s57b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57c", "pass": 1, "name": "s57c-control-minimal", "sha256": "609cbac70075969af496dfc51ade53f165d219911c9f88733099e5f95b03fe21", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00006__wfv__s57c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57c", "pass": 2, "name": "s57c-control-minimal", "sha256": "609cbac70075969af496dfc51ade53f165d219911c9f88733099e5f95b03fe21", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00006__wfv__s57c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57c", "pass": 1, "name": "styles-typed-footnotes", "sha256": "617637d2915468c7427463b578f51b36fc6781bd14b6355a6006cceac8ab287c", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00007__wfv__styles-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:20:06.463 \"Word found unreadable content in 00007__wfv__styles-typed-footnotes.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:20:06.464 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00007__wfv__styles-typed-footnotes.docx)\""]}
{"run": "s57c", "pass": 2, "name": "styles-typed-footnotes", "sha256": "617637d2915468c7427463b578f51b36fc6781bd14b6355a6006cceac8ab287c", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00007__wfv__styles-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:23:04.225 \"Word found unreadable content in 00007__wfv__styles-typed-footnotes.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:23:04.227 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00007__wfv__styles-typed-footnotes.docx)\""]}
{"run": "s57c", "pass": 1, "name": "footer1-referenced-typed-styles", "sha256": "c1e11e67de461ed78a21cc84cc41c4c9dc9be248de41233e98a849fc0a4136f1", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00003__wfv__footer1-referenced-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:19:27.248 'Word found unreadable content in 00003__wfv__footer1-referenced-typed-styles.docx. Do you want to r … ? If you trust the source of this document, click Yes.'"]}
{"run": "s57c", "pass": 2, "name": "footer1-referenced-typed-styles", "sha256": "c1e11e67de461ed78a21cc84cc41c4c9dc9be248de41233e98a849fc0a4136f1", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00003__wfv__footer1-referenced-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:22:13.917 \"Word found unreadable content in 00003__wfv__footer1-referenced-typed-styles.docx. Do you want to r … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:22:13.917 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__footer1-referenced-typed-...)\""]}
{"run": "s57c", "pass": 1, "name": "footer1-referenced-typed-main", "sha256": "a844faa237b4cf11d1035522fc7016725a21da63928798ab15214d7672f5fdae", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00000__wfv__footer1-referenced-typed-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:17:30.197 'Word found unreadable content in 00000__wfv__footer1-referenced-typed-main.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:17:30.735 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__footer1-referenced-typed-...)\""]}
{"run": "s57c", "pass": 2, "name": "footer1-referenced-typed-main", "sha256": "a844faa237b4cf11d1035522fc7016725a21da63928798ab15214d7672f5fdae", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00000__wfv__footer1-referenced-typed-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:20:33.439 'Word found unreadable content in 00000__wfv__footer1-referenced-typed-main.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:20:34.196 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__footer1-referenced-typed-...)\""]}
{"run": "s57c", "pass": 1, "name": "footer1-referenced-typed-numbering", "sha256": "0b5913f49e90938b394b705e671888bd69d733a5eec9abc367a5fd5519786d3f", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00001__wfv__footer1-referenced-typed-numbering.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:18:15.977 Microsoft Word, Word found unreadable content in 00001__wfv__footer1-referenced-typed-numbering.docx … t? If you trust the source of this document, click Yes.", "2026-10-26 13:18:16.047 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__footer1-referenced-typed-...)'"]}
{"run": "s57c", "pass": 2, "name": "footer1-referenced-typed-numbering", "sha256": "0b5913f49e90938b394b705e671888bd69d733a5eec9abc367a5fd5519786d3f", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00001__wfv__footer1-referenced-typed-numbering.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:21:25.379 Microsoft Word, Word found unreadable content in 00001__wfv__footer1-referenced-typed-numbering.docx … t? If you trust the source of this document, click Yes.", "2026-10-26 13:21:26.087 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__footer1-referenced-typed-...)\""]}
{"run": "s57c", "pass": 1, "name": "footer1-referenced-typed-settings", "sha256": "b0d85ca51f8e570124eefc871f1f13117761ea1134d7b00fbc2261cacb3cb165", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00002__wfv__footer1-referenced-typed-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:18:51.632 'Word found unreadable content in 00002__wfv__footer1-referenced-typed-settings.docx. Do you want to … ? If you trust the source of this document, click Yes.'"]}
{"run": "s57c", "pass": 2, "name": "footer1-referenced-typed-settings", "sha256": "b0d85ca51f8e570124eefc871f1f13117761ea1134d7b00fbc2261cacb3cb165", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00002__wfv__footer1-referenced-typed-settings.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:22:09.507 Microsoft Word, Word found unreadable content in 00002__wfv__footer1-referenced-typed-settings.docx. … t? If you trust the source of this document, click Yes."]}
{"run": "s57c", "pass": 1, "name": "header1-referenced-typed-main", "sha256": "7e26835eb7150098d5aba69b06362270a3ca8bddf3b16ffd3d7101fa5030b4fc", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00004__wfv__header1-referenced-typed-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:20:02.825 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__header1-referenced-typed-...)'", "2026-10-26 13:20:03.052 \"Word found unreadable content in 00004__wfv__header1-referenced-typed-main.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57c", "pass": 2, "name": "header1-referenced-typed-main", "sha256": "7e26835eb7150098d5aba69b06362270a3ca8bddf3b16ffd3d7101fa5030b4fc", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00004__wfv__header1-referenced-typed-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:22:57.666 Microsoft Word, Word found unreadable content in 00004__wfv__header1-referenced-typed-main.docx. Do  … t? If you trust the source of this document, click Yes."]}
{"run": "s57c", "pass": 1, "name": "s57c-control-minimal-end", "sha256": "0c73b5b2075522cb5f2b86769f9171883f0f10de24e1d8705107f5bcd78e376d", "observedAt": "2026-10-26T17:20:06+00:00", "staged": "00005__wfv__s57c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57c", "pass": 2, "name": "s57c-control-minimal-end", "sha256": "0c73b5b2075522cb5f2b86769f9171883f0f10de24e1d8705107f5bcd78e376d", "observedAt": "2026-10-26T17:23:25+00:00", "staged": "00005__wfv__s57c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 1, "name": "s57d-control-minimal", "sha256": "0c73b5b2075522cb5f2b86769f9171883f0f10de24e1d8705107f5bcd78e376d", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00007__wfv__s57d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 2, "name": "s57d-control-minimal", "sha256": "0c73b5b2075522cb5f2b86769f9171883f0f10de24e1d8705107f5bcd78e376d", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00007__wfv__s57d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 1, "name": "header1-referenced-typed-styles", "sha256": "158e1abfd05cea588210d4f3c8d32529a3d0ce75cd6fff345bd514613ee17c1d", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00005__wfv__header1-referenced-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:25:11.773 Microsoft Word, Word found unreadable content in 00005__wfv__header1-referenced-typed-styles.docx. D … t? If you trust the source of this document, click Yes.", "2026-10-26 13:25:12.516 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__header1-referenced-typed-...)\""]}
{"run": "s57d", "pass": 2, "name": "header1-referenced-typed-styles", "sha256": "158e1abfd05cea588210d4f3c8d32529a3d0ce75cd6fff345bd514613ee17c1d", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00005__wfv__header1-referenced-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:27:16.118 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00005__wfv__header1-referenced-typed-...)'", "2026-10-26 13:27:16.229 \"Word found unreadable content in 00005__wfv__header1-referenced-typed-styles.docx. Do you want to r … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57d", "pass": 1, "name": "glossary-styles-main-footer-coreach", "sha256": "3727640958988634ba037535bc87c7457a5a6378c63b1081d51f4816d0ac0e93", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00004__wfv__glossary-styles-main-footer-coreach.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:24:21.736 \"Word found unreadable content in 00004__wfv__glossary-styles-main-footer-coreach.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57d", "pass": 2, "name": "glossary-styles-main-footer-coreach", "sha256": "3727640958988634ba037535bc87c7457a5a6378c63b1081d51f4816d0ac0e93", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00004__wfv__glossary-styles-main-footer-coreach.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:26:14.439 \"Word found unreadable content in 00004__wfv__glossary-styles-main-footer-coreach.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57d", "pass": 1, "name": "customizations-noext-refused", "sha256": "1163f74dd346f646463d9de4dd637839f4ae4d74228f3b31c08fcc3401307986", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00002__wfv__customizations-noext-refused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:24:04.813 \"Word found unreadable content in 00002__wfv__customizations-noext-refused.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57d", "pass": 2, "name": "customizations-noext-refused", "sha256": "1163f74dd346f646463d9de4dd637839f4ae4d74228f3b31c08fcc3401307986", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00002__wfv__customizations-noext-refused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:26:01.397 \"Word found unreadable content in 00002__wfv__customizations-noext-refused.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57d", "pass": 1, "name": "customizations-noext-repaired-calibration", "sha256": "d78e36f247b7e0b3ad29a356a6c00ef65f230c65cee1a9ba7f8564215dba5b4b", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00003__wfv__customizations-noext-repaired-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customizations-noext-repaired-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 2, "name": "customizations-noext-repaired-calibration", "sha256": "d78e36f247b7e0b3ad29a356a6c00ef65f230c65cee1a9ba7f8564215dba5b4b", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00003__wfv__customizations-noext-repaired-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customizations-noext-repaired-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 1, "name": "customizations-bin-refused", "sha256": "2d6ad179d337d957f42d512558c364436ba76a9d78fa13273d74672c0dceab88", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00000__wfv__customizations-bin-refused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:23:49.522 'Word found unreadable content in 00000__wfv__customizations-bin-refused.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:23:50.127 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__customizations-bin-refuse...)\""]}
{"run": "s57d", "pass": 2, "name": "customizations-bin-refused", "sha256": "2d6ad179d337d957f42d512558c364436ba76a9d78fa13273d74672c0dceab88", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00000__wfv__customizations-bin-refused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:25:44.681 'Word found unreadable content in 00000__wfv__customizations-bin-refused.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:25:45.295 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__customizations-bin-refuse...)\""]}
{"run": "s57d", "pass": 1, "name": "customizations-bin-repaired-calibration", "sha256": "54425e5a751ebfd6b61add0559a8932aa774dabaef01abf05cca676d9127d416", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00001__wfv__customizations-bin-repaired-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customizations-bin-repaired-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 2, "name": "customizations-bin-repaired-calibration", "sha256": "54425e5a751ebfd6b61add0559a8932aa774dabaef01abf05cca676d9127d416", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00001__wfv__customizations-bin-repaired-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customizations-bin-repaired-calibration_byword.pdf (434557 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 1, "name": "s57d-control-minimal-end", "sha256": "4ebc5fc7a77793b4c282b2f71291b16319110212a72be9fbf34884fd3cd69bba", "observedAt": "2026-10-26T17:25:13+00:00", "staged": "00006__wfv__s57d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57d", "pass": 2, "name": "s57d-control-minimal-end", "sha256": "4ebc5fc7a77793b4c282b2f71291b16319110212a72be9fbf34884fd3cd69bba", "observedAt": "2026-10-26T17:27:17+00:00", "staged": "00006__wfv__s57d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57e", "pass": 1, "name": "s57e-control-minimal", "sha256": "0aa8dce5d97ed3905ad20ada6346d235dcbf9888a80e702cf85bde02f087a073", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00001__wfv__s57e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57e", "pass": 2, "name": "s57e-control-minimal", "sha256": "0aa8dce5d97ed3905ad20ada6346d235dcbf9888a80e702cf85bde02f087a073", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00001__wfv__s57e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57e", "pass": 1, "name": "styles-charset-read-header", "sha256": "35526b2da46eb9aae1ae05a393e0cedfb68f3e928d8ca432bdbc84523dd33f39", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00005__wfv__styles-charset-read-header.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:27:56.213 'Word found unreadable content in 00005__wfv__styles-charset-read-header.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:27:56.736 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-charset-read-heade...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-charset-read-header", "sha256": "35526b2da46eb9aae1ae05a393e0cedfb68f3e928d8ca432bdbc84523dd33f39", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00005__wfv__styles-charset-read-header.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:24.212 'Word found unreadable content in 00005__wfv__styles-charset-read-header.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:24.749 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-charset-read-heade...)\""]}
{"run": "s57e", "pass": 1, "name": "styles-charset-read-comments", "sha256": "242becce0a9acfd3e4894cb5b0efd6b34d5d2d37a66cbb3f65924d1a95f65d6a", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00002__wfv__styles-charset-read-comments.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:27:43.697 'Word found unreadable content in 00002__wfv__styles-charset-read-comments.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:27:44.497 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-charset-read-comme...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-charset-read-comments", "sha256": "242becce0a9acfd3e4894cb5b0efd6b34d5d2d37a66cbb3f65924d1a95f65d6a", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00002__wfv__styles-charset-read-comments.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:11.646 'Word found unreadable content in 00002__wfv__styles-charset-read-comments.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:12.171 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-charset-read-comme...)\""]}
{"run": "s57e", "pass": 1, "name": "styles-charset-read-footnotes", "sha256": "830bef6fe25e6346ed30afeb2b1cd7320178f13859afb5dd00ce5d55591d7399", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00004__wfv__styles-charset-read-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:27:52.046 'Word found unreadable content in 00004__wfv__styles-charset-read-footnotes.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:27:52.837 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-charset-read-footn...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-charset-read-footnotes", "sha256": "830bef6fe25e6346ed30afeb2b1cd7320178f13859afb5dd00ce5d55591d7399", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00004__wfv__styles-charset-read-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:20.029 'Word found unreadable content in 00004__wfv__styles-charset-read-footnotes.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:20.570 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-charset-read-footn...)\""]}
{"run": "s57e", "pass": 1, "name": "styles-charset-read-endnotes", "sha256": "f9f60f2fb8997592b182a32b896efd7d81cf3972e2ed3427cc33ccad62024788", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00003__wfv__styles-charset-read-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:27:47.862 'Word found unreadable content in 00003__wfv__styles-charset-read-endnotes.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:27:48.353 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-charset-read-endno...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-charset-read-endnotes", "sha256": "f9f60f2fb8997592b182a32b896efd7d81cf3972e2ed3427cc33ccad62024788", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00003__wfv__styles-charset-read-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:15.830 'Word found unreadable content in 00003__wfv__styles-charset-read-endnotes.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:16.382 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-charset-read-endno...)\""]}
{"run": "s57e", "pass": 1, "name": "styles-exact-read-header-calibration", "sha256": "7cd14ebc0aa7f84aaf205b50d3a8f4ed5870f5e636ad45f7e0e7291eb9352421", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00007__wfv__styles-exact-read-header-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:04.563 'Word found unreadable content in 00007__wfv__styles-exact-read-header-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:05.104 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-exact-read-header-...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-exact-read-header-calibration", "sha256": "7cd14ebc0aa7f84aaf205b50d3a8f4ed5870f5e636ad45f7e0e7291eb9352421", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00007__wfv__styles-exact-read-header-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:32.562 'Word found unreadable content in 00007__wfv__styles-exact-read-header-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:33.364 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-exact-read-header-...)\""]}
{"run": "s57e", "pass": 1, "name": "styles-exact-read-comments-calibration", "sha256": "21a2c19651d13d9a24e2dcb4b1446e78f4d60ab6bb89a26b7619cdc62e687dd7", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00006__wfv__styles-exact-read-comments-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:00.379 'Word found unreadable content in 00006__wfv__styles-exact-read-comments-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:00.886 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-exact-read-comment...)\""]}
{"run": "s57e", "pass": 2, "name": "styles-exact-read-comments-calibration", "sha256": "21a2c19651d13d9a24e2dcb4b1446e78f4d60ab6bb89a26b7619cdc62e687dd7", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00006__wfv__styles-exact-read-comments-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:28.380 'Word found unreadable content in 00006__wfv__styles-exact-read-comments-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:28.886 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-exact-read-comment...)\""]}
{"run": "s57e", "pass": 1, "name": "s57e-control-minimal-end", "sha256": "da7e7c5a27003b236c846a37cee9c3f2206f057cc4e6eb542639d516edc912fa", "observedAt": "2026-10-26T17:28:05+00:00", "staged": "00000__wfv__s57e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57e", "pass": 2, "name": "s57e-control-minimal-end", "sha256": "da7e7c5a27003b236c846a37cee9c3f2206f057cc4e6eb542639d516edc912fa", "observedAt": "2026-10-26T17:28:33+00:00", "staged": "00000__wfv__s57e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 1, "name": "s57f-control-minimal", "sha256": "da7e7c5a27003b236c846a37cee9c3f2206f057cc4e6eb542639d516edc912fa", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00005__wfv__s57f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 2, "name": "s57f-control-minimal", "sha256": "da7e7c5a27003b236c846a37cee9c3f2206f057cc4e6eb542639d516edc912fa", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00005__wfv__s57f-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57f-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 1, "name": "styles-exact-read-footnotes-calibration", "sha256": "a0e211c406472b638d859ff7cbe4df029ad0771205269bdd7790f96f20730c43", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00007__wfv__styles-exact-read-footnotes-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:29:12.245 'Word found unreadable content in 00007__wfv__styles-exact-read-footnotes-calibration.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:29:12.769 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__styles-exact-read-footnot...)\""]}
{"run": "s57f", "pass": 2, "name": "styles-exact-read-footnotes-calibration", "sha256": "a0e211c406472b638d859ff7cbe4df029ad0771205269bdd7790f96f20730c43", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00007__wfv__styles-exact-read-footnotes-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:31:41.665 Microsoft Word, Word found unreadable content in 00007__wfv__styles-exact-read-footnotes-calibration … t? If you trust the source of this document, click Yes."]}
{"run": "s57f", "pass": 1, "name": "styles-exact-read-endnotes-calibration", "sha256": "66ca502ed802554c7bb21d6325b013c92fa056732c2cbc38a42eeb7ef64c98a0", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00006__wfv__styles-exact-read-endnotes-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:29:08.048 'Word found unreadable content in 00006__wfv__styles-exact-read-endnotes-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:29:08.587 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__styles-exact-read-endnote...)\""]}
{"run": "s57f", "pass": 2, "name": "styles-exact-read-endnotes-calibration", "sha256": "66ca502ed802554c7bb21d6325b013c92fa056732c2cbc38a42eeb7ef64c98a0", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00006__wfv__styles-exact-read-endnotes-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:30:57.901 \"Word found unreadable content in 00006__wfv__styles-exact-read-endnotes-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57f", "pass": 1, "name": "glossary-rels-hyperlink-targetmode-lowercase-external", "sha256": "1ac1e13540f1e6a86973f72605531f692d41d2b05d45b78859416a833115fa35", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00003__wfv__glossary-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:29:03.630 'Word found unreadable content in 00003__wfv__glossary-rels-hyperlink-targetmode-lowercase-ext.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:29:04.153 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__glossary-rels-hyperlink-t...)\""]}
{"run": "s57f", "pass": 2, "name": "glossary-rels-hyperlink-targetmode-lowercase-external", "sha256": "1ac1e13540f1e6a86973f72605531f692d41d2b05d45b78859416a833115fa35", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00003__wfv__glossary-rels-hyperlink-targetmode-lowercase-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:30:41.183 \"Word found unreadable content in 00003__wfv__glossary-rels-hyperlink-targetmode-lowercase-ext.... D … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:31:55.943 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__glossary-rels-hyperlink-t...)\""]}
{"run": "s57f", "pass": 1, "name": "glossary-rels-hyperlink-targetmode-external-calibration", "sha256": "3078096a815ba072798d840ddcc9bb85b4ec1c7b6a0e2cf0d7f868dddb267714", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00002__wfv__glossary-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-rels-hyperlink-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 2, "name": "glossary-rels-hyperlink-targetmode-external-calibration", "sha256": "3078096a815ba072798d840ddcc9bb85b4ec1c7b6a0e2cf0d7f868dddb267714", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00002__wfv__glossary-rels-hyperlink-targetmode-external-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-rels-hyperlink-targetmode-external-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 1, "name": "footnotes-nosidecar-chart", "sha256": "f5fe300bcbdc13e8cdb0a9a44d3c6a2eee22046da23b5f0f2de0ee4484f1596f", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00001__wfv__footnotes-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:59.535 'Word found unreadable content in 00001__wfv__footnotes-nosidecar-chart.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:29:00.406 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__footnotes-nosidecar-chart...)\""]}
{"run": "s57f", "pass": 2, "name": "footnotes-nosidecar-chart", "sha256": "f5fe300bcbdc13e8cdb0a9a44d3c6a2eee22046da23b5f0f2de0ee4484f1596f", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00001__wfv__footnotes-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:30:28.315 Microsoft Word, Word found unreadable content in 00001__wfv__footnotes-nosidecar-chart.docx. Do you  … t? If you trust the source of this document, click Yes."]}
{"run": "s57f", "pass": 1, "name": "comments-nosidecar-chart", "sha256": "48607444445ed090bdc764bf074ed3d0af965fec0c24600541408a7d0ff3cdf3", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00000__wfv__comments-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:28:55.311 'Word found unreadable content in 00000__wfv__comments-nosidecar-chart.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:28:56.154 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-nosidecar-chart....)\""]}
{"run": "s57f", "pass": 2, "name": "comments-nosidecar-chart", "sha256": "48607444445ed090bdc764bf074ed3d0af965fec0c24600541408a7d0ff3cdf3", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00000__wfv__comments-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:29:35.562 'Word found unreadable content in 00000__wfv__comments-nosidecar-chart.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:29:36.101 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-nosidecar-chart....)\""]}
{"run": "s57f", "pass": 1, "name": "s57f-control-minimal-end", "sha256": "97d90bf4ec540dde2cb9fdf277e86378e1cf47ceeb7ae262e684e99e34ad8251", "observedAt": "2026-10-26T17:29:26+00:00", "staged": "00004__wfv__s57f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57f", "pass": 2, "name": "s57f-control-minimal-end", "sha256": "97d90bf4ec540dde2cb9fdf277e86378e1cf47ceeb7ae262e684e99e34ad8251", "observedAt": "2026-10-26T17:31:55+00:00", "staged": "00004__wfv__s57f-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57f-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "s57g-control-minimal", "sha256": "18228f0990d5c7230688e7f47a9dfb2fe40ba3faa9b2f1b12518b4a61b32ca7d", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00007__wfv__s57g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "s57g-control-minimal", "sha256": "18228f0990d5c7230688e7f47a9dfb2fe40ba3faa9b2f1b12518b4a61b32ca7d", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00007__wfv__s57g-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57g-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "glossary-nosidecar-chart", "sha256": "fab66d767d81f3a04a49f1af766007727aa74568ce63905d79bd51b53177b4ed", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00002__wfv__glossary-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:32:18.432 'Word found unreadable content in 00002__wfv__glossary-nosidecar-chart.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:32:19.272 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__glossary-nosidecar-chart....)\""]}
{"run": "s57g", "pass": 2, "name": "glossary-nosidecar-chart", "sha256": "fab66d767d81f3a04a49f1af766007727aa74568ce63905d79bd51b53177b4ed", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00002__wfv__glossary-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:32:48.547 'Word found unreadable content in 00002__wfv__glossary-nosidecar-chart.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:32:49.438 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__glossary-nosidecar-chart....)\""]}
{"run": "s57g", "pass": 1, "name": "main-nosidecar-chart", "sha256": "87dced31c409fcd2cd65dc6aaf0df85119772ac5cd360972d8362176bee4204a", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00004__wfv__main-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:32:35.835 \"Word found unreadable content in 00004__wfv__main-nosidecar-chart.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57g", "pass": 2, "name": "main-nosidecar-chart", "sha256": "87dced31c409fcd2cd65dc6aaf0df85119772ac5cd360972d8362176bee4204a", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00004__wfv__main-nosidecar-chart.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:33:05.985 \"Word found unreadable content in 00004__wfv__main-nosidecar-chart.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s57g", "pass": 1, "name": "footnotes-nosidecar-text-calibration", "sha256": "da8dc994cfa8023fbccad5efd5fc133bf6ce6fa543993aba3bc240d1e667873d", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00001__wfv__footnotes-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-nosidecar-text-calibration_byword.pdf (14717 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "footnotes-nosidecar-text-calibration", "sha256": "da8dc994cfa8023fbccad5efd5fc133bf6ce6fa543993aba3bc240d1e667873d", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00001__wfv__footnotes-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-nosidecar-text-calibration_byword.pdf (14717 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "comments-nosidecar-text-calibration", "sha256": "2fa3493ecd11ea2e5f24f38f5a6124de38e81e923d4a2f6c3178675aa042cff1", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00000__wfv__comments-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-nosidecar-text-calibration_byword.pdf (32924 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "comments-nosidecar-text-calibration", "sha256": "2fa3493ecd11ea2e5f24f38f5a6124de38e81e923d4a2f6c3178675aa042cff1", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00000__wfv__comments-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-nosidecar-text-calibration_byword.pdf (32924 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "glossary-nosidecar-text-calibration", "sha256": "3fd0cd4bd5266aee59c46c0cdba120f3fef6283e6f868f064324c5af62906e55", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00003__wfv__glossary-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-nosidecar-text-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "glossary-nosidecar-text-calibration", "sha256": "3fd0cd4bd5266aee59c46c0cdba120f3fef6283e6f868f064324c5af62906e55", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00003__wfv__glossary-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-nosidecar-text-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "main-nosidecar-text-calibration", "sha256": "bceea61fadc5f8c030c10301a0fb0712f6d56a6cbdb8dd7650e50388ad3ff8d7", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00005__wfv__main-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-nosidecar-text-calibration_byword.pdf (8418 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "main-nosidecar-text-calibration", "sha256": "bceea61fadc5f8c030c10301a0fb0712f6d56a6cbdb8dd7650e50388ad3ff8d7", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00005__wfv__main-nosidecar-text-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-nosidecar-text-calibration_byword.pdf (8418 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 1, "name": "s57g-control-minimal-end", "sha256": "758215b976d8e37652697268969a5e78a7b88a4c133d9ed4f1985b234df2a973", "observedAt": "2026-10-26T17:32:36+00:00", "staged": "00006__wfv__s57g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s57g", "pass": 2, "name": "s57g-control-minimal-end", "sha256": "758215b976d8e37652697268969a5e78a7b88a4c133d9ed4f1985b234df2a973", "observedAt": "2026-10-26T17:33:07+00:00", "staged": "00006__wfv__s57g-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s57g-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 57 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s57builder.mts`:

```ts
// Session 57 (2026-10-26): the shapes the adversarial reviews of layers 168–179 found word-valid judging without a Word row.
// - #779 (s57a, s57b, first row of s57c): thirteen mapped-type pairs no session showed — the main document, a related
//   settings, numbering or styles part typed by its Override with another mapped Word type (webSettings on every reach;
//   settings typed glossary, footer, footnotes or endnotes; numbering typed glossary, theme or footer; styles typed
//   glossary or footnotes). word-valid blocks every one, citing sessions 49/50 and 53.
// - #778 (rest of s57c, first two rows of s57d): a referenced word/footer1.xml typed styles, main, numbering or settings,
//   a referenced word/header1.xml typed main or styles, and a reached glossary's own styles part a main footer reference
//   also targets. Layer 174 blocks the first three footer rows and the glossary row as session 53's co-reach.
// - #777 (rest of s57d): the attached-toolbar fixtures with their customizations part renamed to word/customizations (no
//   extension) or word/customizations.bin, its relationship, sidecar and Override renamed with it.
// - #776 (s57e, first two rows of s57f): word/styles.xml typed `…styles+xml; charset=utf-8` with a read header, comments,
//   footnotes or endnotes relationship also targeting it, and each with the exact styles type (calibrations).
// - #775 (rest of s57f, s57g): a misspelled TargetMode in a reached glossary's relationships part, and a used footnotes,
//   used comments, reached glossary or main document with no relationships part holding a dangling c:chart r:id, each
//   with a no-reference calibration.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s57a pnpm exec node --import tsx s57builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const MAIN_TYPE = `${WML}.document.main+xml`;
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const DRAWING_NS = `xmlns:wp="${WP}" xmlns:a="${A}" xmlns:c="${C}" xmlns:r="${R}"`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, mode?: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${mode === undefined ? "" : ` TargetMode="${mode}"`}/>`;
const relsPart = (body: string) =>
    `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${body}</Relationships>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const retype = (ct: string, part: string, own: string, type: string) =>
    replaceOnce(ct, `<Override PartName="/${part}" ContentType="${own}"/>`, `<Override PartName="/${part}" ContentType="${type}"/>`);
const control = () => buildDocx({ ...P });

type Kind = "numbering" | "settings";
const KINDS: Record<Kind, { root: string; ct: string }> = {
    numbering: { root: `${XML_DECL}<w:numbering xmlns:w="${W}"/>`, ct: `${WML}.numbering+xml` },
    settings: { root: `${XML_DECL}<w:settings xmlns:w="${W}"/>`, ct: `${WML}.settings+xml` },
};
const TYPES = {
    main: MAIN_TYPE,
    styles: STYLES_TYPE,
    theme: "application/vnd.openxmlformats-officedocument.theme+xml",
    glossary: `${WML}.document.glossary+xml`,
    header: `${WML}.header+xml`,
    footer: `${WML}.footer+xml`,
    footnotes: `${WML}.footnotes+xml`,
    endnotes: `${WML}.endnotes+xml`,
    comments: `${WML}.comments+xml`,
    settings: KINDS.settings.ct,
    numbering: KINDS.numbering.ct,
    webSettings: `${WML}.webSettings+xml`,
};
const STYLES_CHARSET = `${STYLES_TYPE}; charset=utf-8`;

/** The minimal package plus `word/<kind>.xml` related from the main document's sidecar as rId2, typed `type` (sessions 50 and 53). */
const relatedTyped = (kind: Kind, type: string) =>
    buildDocx({
        ...P,
        [`word/${kind}.xml`]: KINDS[kind].root,
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", kind, `${kind}.xml`)),
        [CT]: overrides(P[CT]!, [`word/${kind}.xml`, type]),
    });
const mainTyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, MAIN, MAIN_TYPE, type) });
const stylesRetyped = (type: string): Record<string, string> => ({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) });

/**
 * `parts` with the main document's `r:` prefix declared, `sect` first in its `w:sectPr` and `run` appended inside its
 * only paragraph (story and note references live there, never directly in `w:body`).
 */
const mainWith = (parts: Record<string, string>, sect: string, run = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
const STORY_ROOTS = {
    header: `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r></w:p></w:hdr>`,
    footer: `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r></w:p></w:ftr>`,
};
/** A `word/<story>1.xml` the body references through `w:<story>Reference r:id="rIdS"`, typed `type` by its Override (#778). */
const referencedStoryTyped = (story: "header" | "footer", type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${story}1.xml`]: STORY_ROOTS[story],
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdS", story, `${story}1.xml`)),
                [CT]: overrides(P[CT]!, [`word/${story}1.xml`, type]),
            },
            `<w:${story}Reference w:type="default" r:id="rIdS"/>`,
        ),
    );

/** Each reference that makes a lazy reach of `word/styles.xml` read: a section reference or a run in the body (#776). */
const COREACH = {
    header: { sect: `<w:headerReference w:type="default" r:id="rIdX"/>`, run: "" },
    comments: { sect: "", run: `<w:r><w:commentReference w:id="0"/></w:r>` },
    footnotes: { sect: "", run: `<w:r><w:footnoteReference w:id="1"/></w:r>` },
    endnotes: { sect: "", run: `<w:r><w:endnoteReference w:id="1"/></w:r>` },
};
const stylesCoReach = (type: string, segment: keyof typeof COREACH) => {
    const parts = stylesRetyped(type);
    return buildDocx(
        mainWith(
            { ...parts, [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdX", segment, "styles.xml")) },
            COREACH[segment].sect,
            COREACH[segment].run,
        ),
    );
};

/** Session 52's chart drawing in its own paragraph; `ids` is the reference's id attribute(s), verbatim. */
const chartDrawing = (ids: string) =>
    '<w:p><w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="5486400" cy="3200400"/>' +
    `<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="1" name="Chart 1"/><wp:cNvGraphicFramePr/><a:graphic><a:graphicData uri="${C}">` +
    `<c:chart ${ids}/></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
const TEXT_P = "<w:p><w:r><w:t>x</w:t></w:r></w:p>";

/** The minimal package with a reached glossary: the main document's glossaryDocument relationship, `body` in its one docPart. */
const glossaryParts = (
    body: string,
    sidecar: string | undefined,
    extra: Record<string, string> = {},
    extraTypes: Array<[string, string]> = [],
) => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}" ${DRAWING_NS}><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${body}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    ...(sidecar === undefined ? {} : { "word/glossary/_rels/document.xml.rels": sidecar }),
    ...extra,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(P[CT]!, ["word/glossary/document.xml", TYPES.glossary], ...extraTypes),
});
/** #778: the glossary's own styles part, related by its sidecar, also the target of a footer relationship the main body references. */
const glossaryStylesFooterCoReach = () => {
    const parts = glossaryParts(
        TEXT_P,
        relsPart(relationship("rId1", "styles", "styles.xml")),
        { "word/glossary/styles.xml": P["word/styles.xml"]! },
        [["word/glossary/styles.xml", STYLES_TYPE]],
    );
    return buildDocx(
        mainWith(
            { ...parts, [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "glossary/styles.xml")) },
            `<w:footerReference w:type="default" r:id="rIdF"/>`,
        ),
    );
};
/** #775: a reached glossary whose own sidecar holds an unreferenced hyperlink relationship with `mode` (s55e's shape there). */
const glossaryHyperlink = (mode: string) =>
    buildDocx(glossaryParts(TEXT_P, relsPart(relationship("rId99", "hyperlink", "https://example.com/", mode))));

/** #775: a used notes or comments part with no relationships part, holding `body` (a dangling chart, or text). */
const NOTE_PARTS = {
    footnotes: {
        root: (b: string) => `<w:footnotes xmlns:w="${W}" ${DRAWING_NS}><w:footnote w:id="1">${b}</w:footnote></w:footnotes>`,
        ref: COREACH.footnotes.run,
    },
    comments: {
        root: (b: string) => `<w:comments xmlns:w="${W}" ${DRAWING_NS}><w:comment w:id="0" w:author="a">${b}</w:comment></w:comments>`,
        ref: COREACH.comments.run,
    },
};
const usedNoSidecar = (segment: keyof typeof NOTE_PARTS, body: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${segment}.xml`]: `${XML_DECL}${NOTE_PARTS[segment].root(body)}`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", segment, `${segment}.xml`)),
                [CT]: overrides(P[CT]!, [`word/${segment}.xml`, TYPES[segment]]),
            },
            "",
            NOTE_PARTS[segment].ref,
        ),
    );
const glossaryNoSidecar = (body: string) => buildDocx(glossaryParts(body, undefined));
/** #775: the main document with no relationships part at all (so no styles relationship either), `body` before its w:sectPr. */
const mainNoSidecar = (body: string) => {
    const { [SIDECAR]: _dropped, ...parts } = P;
    return buildDocx({
        ...parts,
        [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" ${DRAWING_NS}`), "<w:sectPr>", `${body}<w:sectPr>`),
    });
};

/** #777: a toolbar fixture with word/customizations.xml renamed to `name`, its relationship, sidecar and Override renamed with it. */
const FIXTURES = {
    refused: "tests/fixtures/broken/package.word-attached-toolbar-utf8.docx",
    repaired: "tests/fixtures/working/package.word-attached-toolbar-utf8-repaired.docx",
};
const customizationsRenamed = async (fixture: keyof typeof FIXTURES, name: string) => {
    const zip = await JSZip.loadAsync(readFileSync(FIXTURES[fixture]));
    const move = async (from: string, to: string) => {
        const entry = zip.file(from);
        if (!entry) throw new Error(`no ${from}`);
        zip.file(to, await entry.async("uint8array"));
        zip.remove(from);
    };
    const edit = async (part: string, from: string, to: string) =>
        zip.file(part, replaceOnce(await zip.file(part)!.async("string"), from, to));
    await move("word/customizations.xml", `word/${name}`);
    await move("word/_rels/customizations.xml.rels", `word/_rels/${name}.rels`);
    await edit(SIDECAR, 'Target="customizations.xml"', `Target="${name}"`);
    await edit(CT, '<Override PartName="/word/customizations.xml"', `<Override PartName="/word/${name}"`);
    return zip.generateAsync({ type: "uint8array", compression: "DEFLATE" });
};

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const pair = (reach: string, type: keyof typeof TYPES): string => `#779: the ${reach} typed by its Override with the ${type} content type`;

const chunks: Record<string, Row[]> = {
    s57a: withControls("s57a", [
        ["main-typed-websettings", pair("main document", "webSettings"), () => mainTyped(TYPES.webSettings)],
        ["settings-typed-websettings", pair("related word/settings.xml", "webSettings"), () => relatedTyped("settings", TYPES.webSettings)],
        ["settings-typed-glossary", pair("related word/settings.xml", "glossary"), () => relatedTyped("settings", TYPES.glossary)],
        ["settings-typed-footer", pair("related word/settings.xml", "footer"), () => relatedTyped("settings", TYPES.footer)],
        ["settings-typed-footnotes", pair("related word/settings.xml", "footnotes"), () => relatedTyped("settings", TYPES.footnotes)],
        ["settings-typed-endnotes", pair("related word/settings.xml", "endnotes"), () => relatedTyped("settings", TYPES.endnotes)],
    ]),
    s57b: withControls("s57b", [
        [
            "numbering-typed-websettings",
            pair("related word/numbering.xml", "webSettings"),
            () => relatedTyped("numbering", TYPES.webSettings),
        ],
        ["numbering-typed-glossary", pair("related word/numbering.xml", "glossary"), () => relatedTyped("numbering", TYPES.glossary)],
        ["numbering-typed-theme", pair("related word/numbering.xml", "theme"), () => relatedTyped("numbering", TYPES.theme)],
        ["numbering-typed-footer", pair("related word/numbering.xml", "footer"), () => relatedTyped("numbering", TYPES.footer)],
        ["styles-typed-websettings", pair("word/styles.xml", "webSettings"), () => buildDocx(stylesRetyped(TYPES.webSettings))],
        ["styles-typed-glossary", pair("word/styles.xml", "glossary"), () => buildDocx(stylesRetyped(TYPES.glossary))],
    ]),
    s57c: withControls("s57c", [
        ["styles-typed-footnotes", pair("word/styles.xml", "footnotes"), () => buildDocx(stylesRetyped(TYPES.footnotes))],
        [
            "footer1-referenced-typed-styles",
            "#778: a word/footer1.xml the body references, typed by its Override with the styles content type",
            () => referencedStoryTyped("footer", TYPES.styles),
        ],
        [
            "footer1-referenced-typed-main",
            "#778: the same footer typed with the main document content type",
            () => referencedStoryTyped("footer", TYPES.main),
        ],
        [
            "footer1-referenced-typed-numbering",
            "#778: the same footer typed with the numbering content type",
            () => referencedStoryTyped("footer", TYPES.numbering),
        ],
        [
            "footer1-referenced-typed-settings",
            "#778: the same footer typed with the settings content type",
            () => referencedStoryTyped("footer", TYPES.settings),
        ],
        [
            "header1-referenced-typed-main",
            "#778: a word/header1.xml the body references, typed with the main document content type",
            () => referencedStoryTyped("header", TYPES.main),
        ],
    ]),
    s57d: withControls("s57d", [
        [
            "header1-referenced-typed-styles",
            "#778: the same header typed with the styles content type",
            () => referencedStoryTyped("header", TYPES.styles),
        ],
        [
            "glossary-styles-main-footer-coreach",
            "#778: a reached glossary's own word/glossary/styles.xml (styles type, related by its sidecar) that a footer relationship the main body references also targets",
            glossaryStylesFooterCoReach,
        ],
        [
            "customizations-noext-refused",
            "#777: the refused toolbar fixture with word/customizations.xml renamed word/customizations (no extension), relationship, sidecar and Override renamed with it",
            () => customizationsRenamed("refused", "customizations"),
        ],
        [
            "customizations-noext-repaired-calibration",
            "#777 calibration: the same rename of the repaired toolbar fixture",
            () => customizationsRenamed("repaired", "customizations"),
        ],
        [
            "customizations-bin-refused",
            "#777: the refused toolbar fixture with word/customizations.xml renamed word/customizations.bin (its Override keeps the keyMapCustomizations type)",
            () => customizationsRenamed("refused", "customizations.bin"),
        ],
        [
            "customizations-bin-repaired-calibration",
            "#777 calibration: the same .bin rename of the repaired toolbar fixture",
            () => customizationsRenamed("repaired", "customizations.bin"),
        ],
    ]),
    s57e: withControls("s57e", [
        [
            "styles-charset-read-header",
            "#776: word/styles.xml typed styles+xml; charset=utf-8, also the target of a header relationship the body references",
            () => stylesCoReach(STYLES_CHARSET, "header"),
        ],
        [
            "styles-charset-read-comments",
            '#776: the same with a comments relationship and a w:commentReference w:id="0" in the body',
            () => stylesCoReach(STYLES_CHARSET, "comments"),
        ],
        [
            "styles-charset-read-footnotes",
            '#776: the same with a footnotes relationship and a w:footnoteReference w:id="1" in the body',
            () => stylesCoReach(STYLES_CHARSET, "footnotes"),
        ],
        [
            "styles-charset-read-endnotes",
            '#776: the same with an endnotes relationship and a w:endnoteReference w:id="1" in the body',
            () => stylesCoReach(STYLES_CHARSET, "endnotes"),
        ],
        [
            "styles-exact-read-header-calibration",
            "#776 calibration: the header co-reach with the exact styles content type",
            () => stylesCoReach(STYLES_TYPE, "header"),
        ],
        [
            "styles-exact-read-comments-calibration",
            "#776 calibration: the comments co-reach with the exact styles content type",
            () => stylesCoReach(STYLES_TYPE, "comments"),
        ],
    ]),
    s57f: withControls("s57f", [
        [
            "styles-exact-read-footnotes-calibration",
            "#776 calibration: the footnotes co-reach with the exact styles content type",
            () => stylesCoReach(STYLES_TYPE, "footnotes"),
        ],
        [
            "styles-exact-read-endnotes-calibration",
            "#776 calibration: the endnotes co-reach with the exact styles content type",
            () => stylesCoReach(STYLES_TYPE, "endnotes"),
        ],
        [
            "glossary-rels-hyperlink-targetmode-lowercase-external",
            '#775: a reached glossary whose relationships part holds an unreferenced hyperlink relationship with TargetMode="external"',
            () => glossaryHyperlink("external"),
        ],
        [
            "glossary-rels-hyperlink-targetmode-external-calibration",
            '#775 calibration: the same with TargetMode="External"',
            () => glossaryHyperlink("External"),
        ],
        [
            "footnotes-nosidecar-chart",
            '#775: a used word/footnotes.xml with no relationships part, footnote 1 holding c:chart r:id="rId1"',
            () => usedNoSidecar("footnotes", chartDrawing('r:id="rId1"')),
        ],
        [
            "comments-nosidecar-chart",
            '#775: a used word/comments.xml with no relationships part, comment 0 holding c:chart r:id="rId1"',
            () => usedNoSidecar("comments", chartDrawing('r:id="rId1"')),
        ],
    ]),
    s57g: withControls("s57g", [
        [
            "glossary-nosidecar-chart",
            '#775: a reached glossary document with no relationships part holding c:chart r:id="rId1"',
            () => glossaryNoSidecar(chartDrawing('r:id="rId1"')),
        ],
        [
            "main-nosidecar-chart",
            '#775: the main document with no relationships part holding c:chart r:id="rId1"',
            () => mainNoSidecar(chartDrawing('r:id="rId1"')),
        ],
        [
            "footnotes-nosidecar-text-calibration",
            "#775 calibration: the used footnotes part with no relationships part, footnote 1 holding text only",
            () => usedNoSidecar("footnotes", TEXT_P),
        ],
        [
            "comments-nosidecar-text-calibration",
            "#775 calibration: the used comments part with no relationships part, comment 0 holding text only",
            () => usedNoSidecar("comments", TEXT_P),
        ],
        [
            "glossary-nosidecar-text-calibration",
            "#775 calibration: the reached glossary with no relationships part, text only",
            () => glossaryNoSidecar(TEXT_P),
        ],
        [
            "main-nosidecar-text-calibration",
            "#775 calibration: the main document with no relationships part, text only",
            () => mainNoSidecar(TEXT_P),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-57 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s57a", "s57b", "s57c", "s57d", "s57e", "s57f", "s57g")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s57/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-57 parts of docs/plans/evidence/word-probes-2026-10-24.md into s57/section.md.

Reads each chunk's specimens.jsonl (validator columns at d93138a9, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s57/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s57a", "s57b", "s57c", "s57d", "s57e", "s57f", "s57g")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s57/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 57: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at d93138a9",
    "",
    "The shapes the adversarial reviews of layers 168–179 found without a Word row "
    "([#775](https://github.com/jandira-tech/docx-validate/issues/775)–"
    "[#779](https://github.com/jandira-tech/docx-validate/issues/779)). Seven chunks, each opening and closing with the minimal "
    "control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from "
    f"its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs "
    f"and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of "
    "the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- #779: each of the 13 mapped-type pairs no session had shown gets the recovery offer. These are the main document typed "
    "webSettings; `word/settings.xml` typed webSettings, glossary, footer, footnotes or endnotes; `word/numbering.xml` typed "
    "webSettings, glossary, theme or footer; and `word/styles.xml` typed webSettings, glossary or footnotes. Word-valid at d93138a9 "
    "already rejects all 13; these rows are the observation its recovery sentences lacked.",
    "- #778: a `word/footer1.xml` the body references gets the recovery offer typed with the styles, main document, numbering or "
    "settings content type; word-valid rejects the first three and accepts the settings row. A `word/header1.xml` the body "
    "references gets the recovery offer typed with the main document or styles content type; word-valid accepts both. A reached "
    "glossary's own styles part that a footer relationship the body references also reaches gets the recovery offer; word-valid "
    "rejects it. Three false negatives.",
    "- #777: the refused attached-toolbar fixture with `word/customizations.xml` renamed without an extension, or to "
    "`word/customizations.bin` (its Override keeping the keyMapCustomizations type), still gets the recovery offer; the same renames "
    "of the repaired fixture open clean. Word-valid accepts both refused rows. Two false negatives.",
    "- #776: `word/styles.xml` typed `…styles+xml; charset=utf-8` and also the target of a header, comments, footnotes or endnotes "
    "relationship the body reads gets the recovery offer, and word-valid rejects all four. The calibrations with the exact styles "
    "type get the recovery offer too, so the refusal does not need the inexact spelling; word-valid rejects only the footnotes "
    "calibration. Three false negatives. The comments, footnotes and endnotes specimens reference an id (`w:commentReference "
    "w:id=\"0\"`, `w:footnoteReference w:id=\"1\"`, `w:endnoteReference w:id=\"1\"`) in a part rooted `w:styles`, so a dangling "
    "reference is a possible confound in those three; the header rows have no such reference.",
    "- #775: a reached glossary whose relationships part holds an unreferenced hyperlink relationship with `TargetMode=\"external\"` "
    "gets the recovery offer; with `External` it opens clean. Word-valid accepts the lowercase row: a false negative. A used "
    "`word/footnotes.xml`, a used `word/comments.xml`, a reached glossary and the main document, each with no relationships part "
    "and holding `c:chart r:id=\"rId1\"`, get the recovery offer, and word-valid rejects all four; their text-only calibrations open "
    "clean.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at d93138a9 | strict at d93138a9 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 57</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 57 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s57builder.mts", ROOT / "s57builder.mts", "ts"), ("compare.py", ROOT / "s57/compare.py", "python"),
                         ("section.py", ROOT / "s57/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s57/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 58: 17:50Z–17:56Z on 2026-10-26, validator columns at bfb8eb75

The confound in session 57's #776 calibrations ([#776](https://github.com/jandira-tech/docx-validate/issues/776)): its comments, footnotes and endnotes co-reach specimens reference an id that `word/styles.xml`, rooted `w:styles`, cannot hold. Two chunks, each opening and closing with the minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 14 of 14 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A used `word/comments.xml` holding comment 5, the body's `w:commentReference` naming `w:id="0"`, gets the recovery offer, and so does a used `word/endnotes.xml` holding endnote 5, the body's `w:endnoteReference` naming `w:id="1"`. The matching-id calibrations open clean. Word-valid at bfb8eb75 accepts both dangling references: two false negatives. A dangling footnote reference was already refused (fixture 1829, `word-footnote-reference-missing`).
- `word/styles.xml`, exact styles type, also the target of a comments, endnotes or footnotes relationship, with no reference in the body, opens clean. Session 57's comments and endnotes co-reach calibrations were therefore refused for their dangling references, not for the co-reach; its header calibration had no such reference.
- A used `word/comments.xml`, `word/endnotes.xml` or `word/footnotes.xml`, its own root with a matching reference, typed by its Override with the styles content type, gets the recovery offer. Word-valid at bfb8eb75 accepts all three: three false negatives.

| Run    | Observed             | Specimen                                      | Shape                                                                                                          | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at bfb8eb75 | strict at bfb8eb75                                                                                    |
| ------ | -------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- |
| `s58a` | 17:50:56Z, 17:54:08Z | `s58a-control-minimal`                        | control                                                                                                        | `3c3a6fb737d5451c` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58a` | 17:50:56Z, 17:54:08Z | `comments-dangling-reference`                 | #776: a used word/comments.xml holding comment 5, the body's w:commentReference naming w:id="0"                | `0df2a5e972d98038` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-marker-missing`, `comment-thread-count-mismatch`, `paraid-missing-element`          |
| `s58a` | 17:50:56Z, 17:54:08Z | `comments-matching-reference-calibration`     | #776 calibration: the same holding comment 0                                                                   | `63c0bd62c80e39df` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                    |
| `s58a` | 17:50:56Z, 17:54:08Z | `endnotes-dangling-reference`                 | #776: a used word/endnotes.xml holding endnote 5, the body's w:endnoteReference naming w:id="1"                | `94a559f3e0e10cfc` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `paraid-missing-element`                                                                     |
| `s58a` | 17:50:56Z, 17:54:08Z | `endnotes-matching-reference-calibration`     | #776 calibration: the same holding endnote 1                                                                   | `d7f604e93195f5fe` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element`                                                                     |
| `s58a` | 17:50:56Z, 17:54:08Z | `styles-exact-comments-coreach-no-reference`  | #776: word/styles.xml (exact styles type) also the target of a comments relationship; no reference in the body | `c4545463a7692867` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58a` | 17:50:56Z, 17:54:08Z | `styles-exact-endnotes-coreach-no-reference`  | #776: the same with an endnotes relationship                                                                   | `3d752f650b35fa24` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58a` | 17:50:56Z, 17:54:08Z | `s58a-control-minimal-end`                    | control                                                                                                        | `feb2c538aa56bbd1` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58b` | 17:52:49Z, 17:56:14Z | `s58b-control-minimal`                        | control                                                                                                        | `feb2c538aa56bbd1` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58b` | 17:52:49Z, 17:56:14Z | `styles-exact-footnotes-coreach-no-reference` | #776: the same with a footnotes relationship                                                                   | `53a9f96b638fd964` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |
| `s58b` | 17:52:49Z, 17:56:14Z | `comments-used-typed-styles`                  | #776/#778: a used word/comments.xml (comment 0, referenced) typed by its Override with the styles content type | `7a205d7cc1fe883f` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element` |
| `s58b` | 17:52:49Z, 17:56:14Z | `endnotes-used-typed-styles`                  | #776/#778: a used word/endnotes.xml (endnote 1, referenced) typed with the styles content type                 | `ec375e8959359da9` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                  |
| `s58b` | 17:52:49Z, 17:56:14Z | `footnotes-used-typed-styles`                 | #776/#778: a used word/footnotes.xml (footnote 1, referenced) typed with the styles content type               | `4720b49dfb7e5fa7` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                  |
| `s58b` | 17:52:49Z, 17:56:14Z | `s58b-control-minimal-end`                    | control                                                                                                        | `feb2c538aa56bbd1` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                 |

<details><summary>Raw records, session 58</summary>

```jsonl
{"run": "s58a", "pass": 1, "name": "s58a-control-minimal", "sha256": "3c3a6fb737d5451ce2f3356eebfb32bf0a1bc8e5d73c73c9719b702550805130", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00005__wfv__s58a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "s58a-control-minimal", "sha256": "3c3a6fb737d5451ce2f3356eebfb32bf0a1bc8e5d73c73c9719b702550805130", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00005__wfv__s58a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 1, "name": "comments-dangling-reference", "sha256": "0df2a5e972d9803871a85bd63d6b66234f2159fd1c4e2c4a2c7db8261381e55c", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00000__wfv__comments-dangling-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:50:32.594 \"Word found unreadable content in 00000__wfv__comments-dangling-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s58a", "pass": 2, "name": "comments-dangling-reference", "sha256": "0df2a5e972d9803871a85bd63d6b66234f2159fd1c4e2c4a2c7db8261381e55c", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00000__wfv__comments-dangling-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:54:00.249 Microsoft Word, Word found unreadable content in 00000__wfv__comments-dangling-reference.docx. Do yo … t? If you trust the source of this document, click Yes."]}
{"run": "s58a", "pass": 1, "name": "comments-matching-reference-calibration", "sha256": "63c0bd62c80e39df5e2a7279be3306eec7f59fa924def31c8a15cd075a21ba45", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00001__wfv__comments-matching-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-matching-reference-calibration_byword.pdf (32928 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "comments-matching-reference-calibration", "sha256": "63c0bd62c80e39df5e2a7279be3306eec7f59fa924def31c8a15cd075a21ba45", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00001__wfv__comments-matching-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-matching-reference-calibration_byword.pdf (32928 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 1, "name": "endnotes-dangling-reference", "sha256": "94a559f3e0e10cfc95ef2094cdc6c7082ddd8512b0796cd9fde7f7510480ebc3", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00002__wfv__endnotes-dangling-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:50:54.378 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00002__wfv__endnotes-dangling-referen...)'", "2026-10-26 13:50:54.570 \"Word found unreadable content in 00002__wfv__endnotes-dangling-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s58a", "pass": 2, "name": "endnotes-dangling-reference", "sha256": "94a559f3e0e10cfc95ef2094cdc6c7082ddd8512b0796cd9fde7f7510480ebc3", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00002__wfv__endnotes-dangling-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:54:06.422 \"Word found unreadable content in 00002__wfv__endnotes-dangling-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\"", "2026-10-26 13:54:06.423 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__endnotes-dangling-referen...)\""]}
{"run": "s58a", "pass": 1, "name": "endnotes-matching-reference-calibration", "sha256": "d7f604e93195f5fe7a8f2ee1574c55ef55377bc980463ab2886eaa773c0fb2cd", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00003__wfv__endnotes-matching-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-matching-reference-calibration_byword.pdf (14992 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "endnotes-matching-reference-calibration", "sha256": "d7f604e93195f5fe7a8f2ee1574c55ef55377bc980463ab2886eaa773c0fb2cd", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00003__wfv__endnotes-matching-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-matching-reference-calibration_byword.pdf (14992 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 1, "name": "styles-exact-comments-coreach-no-reference", "sha256": "c4545463a76928677f063bfe8cc34e413ba6b2d573003dc5861b59fa39dccc0c", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00006__wfv__styles-exact-comments-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-comments-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "styles-exact-comments-coreach-no-reference", "sha256": "c4545463a76928677f063bfe8cc34e413ba6b2d573003dc5861b59fa39dccc0c", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00006__wfv__styles-exact-comments-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-comments-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 1, "name": "styles-exact-endnotes-coreach-no-reference", "sha256": "3d752f650b35fa24056fac769cf3b8b52e006a4907660d91afbd8f5410484a07", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00007__wfv__styles-exact-endnotes-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-endnotes-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "styles-exact-endnotes-coreach-no-reference", "sha256": "3d752f650b35fa24056fac769cf3b8b52e006a4907660d91afbd8f5410484a07", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00007__wfv__styles-exact-endnotes-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-endnotes-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 1, "name": "s58a-control-minimal-end", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:50:56+00:00", "staged": "00004__wfv__s58a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58a", "pass": 2, "name": "s58a-control-minimal-end", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:54:08+00:00", "staged": "00004__wfv__s58a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 1, "name": "s58b-control-minimal", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00004__wfv__s58b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 2, "name": "s58b-control-minimal", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00004__wfv__s58b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 1, "name": "styles-exact-footnotes-coreach-no-reference", "sha256": "53a9f96b638fd96411e94c54ccef3b9561225bd5ea21918b9da4098255099427", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00005__wfv__styles-exact-footnotes-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-footnotes-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 2, "name": "styles-exact-footnotes-coreach-no-reference", "sha256": "53a9f96b638fd96411e94c54ccef3b9561225bd5ea21918b9da4098255099427", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00005__wfv__styles-exact-footnotes-coreach-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-footnotes-coreach-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 1, "name": "comments-used-typed-styles", "sha256": "7a205d7cc1fe883fb6dff8160392d7fa8477be5c1b2bd65e273a42a25747ac31", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00000__wfv__comments-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:51:25.235 \"Word found unreadable content in 00000__wfv__comments-used-typed-styles.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""]}
{"run": "s58b", "pass": 2, "name": "comments-used-typed-styles", "sha256": "7a205d7cc1fe883fb6dff8160392d7fa8477be5c1b2bd65e273a42a25747ac31", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00000__wfv__comments-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:54:33.857 \"Word found unreadable content in 00000__wfv__comments-used-typed-styles.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""]}
{"run": "s58b", "pass": 1, "name": "endnotes-used-typed-styles", "sha256": "ec375e8959359da9a3bf071a0168521ff9e8edb48306e2b63ec6d2e01c5ff082", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00001__wfv__endnotes-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:52:14.830 Microsoft Word, Word found unreadable content in 00001__wfv__endnotes-used-typed-styles.docx. Do you … t? If you trust the source of this document, click Yes."]}
{"run": "s58b", "pass": 2, "name": "endnotes-used-typed-styles", "sha256": "ec375e8959359da9a3bf071a0168521ff9e8edb48306e2b63ec6d2e01c5ff082", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00001__wfv__endnotes-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:55:21.304 'Word found unreadable content in 00001__wfv__endnotes-used-typed-styles.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-26 13:55:21.973 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__endnotes-used-typed-style...)\""]}
{"run": "s58b", "pass": 1, "name": "footnotes-used-typed-styles", "sha256": "4720b49dfb7e5fa790d4db312eaab96d68b4df7603a3b9883c43a3bee87f1790", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00002__wfv__footnotes-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:52:46.367 'Word found unreadable content in 00002__wfv__footnotes-used-typed-styles.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s58b", "pass": 2, "name": "footnotes-used-typed-styles", "sha256": "4720b49dfb7e5fa790d4db312eaab96d68b4df7603a3b9883c43a3bee87f1790", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00002__wfv__footnotes-used-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 13:56:11.782 'Word found unreadable content in 00002__wfv__footnotes-used-typed-styles.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"]}
{"run": "s58b", "pass": 1, "name": "s58b-control-minimal-end", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:52:49+00:00", "staged": "00003__wfv__s58b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s58b", "pass": 2, "name": "s58b-control-minimal-end", "sha256": "feb2c538aa56bbd1fca2dd4df049151320679ec256f5c2c2018780f36450c0da", "observedAt": "2026-10-26T17:56:14+00:00", "staged": "00003__wfv__s58b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s58b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 58 builder, cross-check and section scripts</summary>

Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s58builder.mts`:

```ts
// Session 58 (2026-10-26): the confound in session 57's #776 calibrations. s57e/s57f's comments, footnotes and endnotes
// co-reach specimens reference an id (`w:commentReference w:id="0"`, `w:footnoteReference`/`w:endnoteReference w:id="1"`)
// that word/styles.xml, rooted w:styles, cannot hold, so each row carries a dangling reference besides the co-reach.
// - s58a: a dangling comment reference and a dangling endnote reference alone (well-formed parts lacking the id), each
//   with its matching-id calibration; and the styles co-reach by a comments or endnotes relationship with no reference.
// - s58b: the same no-reference co-reach by a footnotes relationship, and a used comments, endnotes or footnotes part
//   (its own root, matching reference) typed by its Override with the styles content type (#778's class on other stories).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s58a pnpm exec node --import tsx s58builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>x</w:t></w:r></w:p>";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/** `parts` with the main document's `r:` prefix declared and `run` appended inside its only paragraph (session 57's mainWith). */
const mainWith = (parts: Record<string, string>, run: string): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "</w:r></w:p>", `</w:r>${run}</w:p>`),
});

/** Each story: its own root holding one item with `id`, its content type, and the body run referencing `id`. */
const STORIES = {
    comments: {
        root: (id: string) =>
            `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment></w:comments>`,
        type: `${WML}.comments+xml`,
        ref: (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`,
    },
    endnotes: {
        root: (id: string) => `${XML_DECL}<w:endnotes xmlns:w="${W}"><w:endnote w:id="${id}">${TEXT_P}</w:endnote></w:endnotes>`,
        type: `${WML}.endnotes+xml`,
        ref: (id: string) => `<w:r><w:endnoteReference w:id="${id}"/></w:r>`,
    },
    footnotes: {
        root: (id: string) => `${XML_DECL}<w:footnotes xmlns:w="${W}"><w:footnote w:id="${id}">${TEXT_P}</w:footnote></w:footnotes>`,
        type: `${WML}.footnotes+xml`,
        ref: (id: string) => `<w:r><w:footnoteReference w:id="${id}"/></w:r>`,
    },
};
type Story = keyof typeof STORIES;

/** A used `word/<story>.xml` holding item `held`, the body referencing `referenced`, typed `type` (its own type by default). */
const usedStory = (story: Story, held: string, referenced: string, type: string = STORIES[story].type) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${story}.xml`]: STORIES[story].root(held),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", story, `${story}.xml`)),
                [CT]: overrides(P[CT]!, [`word/${story}.xml`, type]),
            },
            STORIES[story].ref(referenced),
        ),
    );
/** word/styles.xml, exact styles type, also the target of a `story` relationship; the body references nothing. */
const stylesCoReachNoReference = (story: Story) =>
    buildDocx({ ...P, [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdX", story, "styles.xml")) });

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s58a: withControls("s58a", [
        [
            "comments-dangling-reference",
            '#776: a used word/comments.xml holding comment 5, the body\'s w:commentReference naming w:id="0"',
            () => usedStory("comments", "5", "0"),
        ],
        ["comments-matching-reference-calibration", "#776 calibration: the same holding comment 0", () => usedStory("comments", "0", "0")],
        [
            "endnotes-dangling-reference",
            '#776: a used word/endnotes.xml holding endnote 5, the body\'s w:endnoteReference naming w:id="1"',
            () => usedStory("endnotes", "5", "1"),
        ],
        ["endnotes-matching-reference-calibration", "#776 calibration: the same holding endnote 1", () => usedStory("endnotes", "1", "1")],
        [
            "styles-exact-comments-coreach-no-reference",
            "#776: word/styles.xml (exact styles type) also the target of a comments relationship; no reference in the body",
            () => stylesCoReachNoReference("comments"),
        ],
        [
            "styles-exact-endnotes-coreach-no-reference",
            "#776: the same with an endnotes relationship",
            () => stylesCoReachNoReference("endnotes"),
        ],
    ]),
    s58b: withControls("s58b", [
        [
            "styles-exact-footnotes-coreach-no-reference",
            "#776: the same with a footnotes relationship",
            () => stylesCoReachNoReference("footnotes"),
        ],
        [
            "comments-used-typed-styles",
            "#776/#778: a used word/comments.xml (comment 0, referenced) typed by its Override with the styles content type",
            () => usedStory("comments", "0", "0", STYLES_TYPE),
        ],
        [
            "endnotes-used-typed-styles",
            "#776/#778: a used word/endnotes.xml (endnote 1, referenced) typed with the styles content type",
            () => usedStory("endnotes", "1", "1", STYLES_TYPE),
        ],
        [
            "footnotes-used-typed-styles",
            "#776/#778: a used word/footnotes.xml (footnote 1, referenced) typed with the styles content type",
            () => usedStory("footnotes", "1", "1", STYLES_TYPE),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-58 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s58a", "s58b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s58/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-58 parts of docs/plans/evidence/word-probes-2026-10-24.md into s58/section.md.

Reads each chunk's specimens.jsonl (validator columns at bfb8eb75, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s58/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s58a", "s58b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s58/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 58: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at bfb8eb75",
    "",
    "The confound in session 57's #776 calibrations "
    "([#776](https://github.com/jandira-tech/docx-validate/issues/776)): its comments, footnotes and endnotes co-reach specimens "
    "reference an id that `word/styles.xml`, rooted `w:styles`, cannot hold. Two chunks, each opening and closing with the minimal "
    "control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from "
    f"its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs "
    f"and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of "
    "the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A used `word/comments.xml` holding comment 5, the body's `w:commentReference` naming `w:id=\"0\"`, gets the recovery offer, "
    "and so does a used `word/endnotes.xml` holding endnote 5, the body's `w:endnoteReference` naming `w:id=\"1\"`. The "
    "matching-id calibrations open clean. Word-valid at bfb8eb75 accepts both dangling references: two false negatives. A dangling "
    "footnote reference was already refused (fixture 1829, `word-footnote-reference-missing`).",
    "- `word/styles.xml`, exact styles type, also the target of a comments, endnotes or footnotes relationship, with no reference in "
    "the body, opens clean. Session 57's comments and endnotes co-reach calibrations were therefore refused for their dangling "
    "references, not for the co-reach; its header calibration had no such reference.",
    "- A used `word/comments.xml`, `word/endnotes.xml` or `word/footnotes.xml`, its own root with a matching reference, typed by its "
    "Override with the styles content type, gets the recovery offer. Word-valid at bfb8eb75 accepts all three: three false "
    "negatives.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at bfb8eb75 | strict at bfb8eb75 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 58</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 58 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second runs and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s58builder.mts", ROOT / "s58builder.mts", "ts"), ("compare.py", ROOT / "s58/compare.py", "python"),
                         ("section.py", ROOT / "s58/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s58/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 59: 18:37Z–18:37Z on 2026-10-26, validator columns at bfb8eb75

The three eager mapped-type pairs no session had shown ([#779](https://github.com/jandira-tech/docx-validate/issues/779)). Keying each mismatch recovery sentence by its pair left `word/styles.xml` typed endnotes, and a related `word/numbering.xml` typed footnotes or endnotes, with no Word row in sessions 49, 50, 53, 56 or 57. One chunk, opening and closing with the minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 5 of 5 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- All three pairs get the recovery offer, as every other eager pair did. Word-valid at bfb8eb75 already rejects all three, so no verdict changes; these rows are the observation their findings' recovery sentences lacked.

| Run    | Observed             | Specimen                    | Shape                                                                                              | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at bfb8eb75                     | strict at bfb8eb75                         |
| ------ | -------------------- | --------------------------- | -------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | ------------------------------------------ |
| `s59a` | 18:37:01Z, 18:37:26Z | `s59a-control-minimal`      | control                                                                                            | `4a1ff3c351b0a83c` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                      |
| `s59a` | 18:37:01Z, 18:37:26Z | `styles-typed-endnotes`     | #779 residue: the word/styles.xml typed by its Override with the endnotes content type             | `6d498bd40c567687` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch` |
| `s59a` | 18:37:01Z, 18:37:26Z | `numbering-typed-footnotes` | #779 residue: the related word/numbering.xml typed by its Override with the footnotes content type | `ef3014c3f6965070` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch` |
| `s59a` | 18:37:01Z, 18:37:26Z | `numbering-typed-endnotes`  | #779 residue: the related word/numbering.xml typed by its Override with the endnotes content type  | `6ef55472e769e130` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch` |
| `s59a` | 18:37:01Z, 18:37:26Z | `s59a-control-minimal-end`  | control                                                                                            | `4a1ff3c351b0a83c` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                      |

<details><summary>Raw records, session 59</summary>

```jsonl
{"run": "s59a", "pass": 1, "name": "s59a-control-minimal", "sha256": "4a1ff3c351b0a83cb04cd74be12baf1a81cf5fb2e039369b51de6747e0afcc08", "observedAt": "2026-10-26T18:37:01+00:00", "staged": "00003__wfv__s59a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s59a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s59a", "pass": 2, "name": "s59a-control-minimal", "sha256": "4a1ff3c351b0a83cb04cd74be12baf1a81cf5fb2e039369b51de6747e0afcc08", "observedAt": "2026-10-26T18:37:26+00:00", "staged": "00003__wfv__s59a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s59a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s59a", "pass": 1, "name": "styles-typed-endnotes", "sha256": "6d498bd40c567687854fc08323959a02b2d0e9fc5cd6eaa0d02211095842df36", "observedAt": "2026-10-26T18:37:01+00:00", "staged": "00004__wfv__styles-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:37:00.821 'Word found unreadable content in 00004__wfv__styles-typed-endnotes.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 14:37:01.654 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00004__wfv__styles-typed-endnotes.docx)\""]}
{"run": "s59a", "pass": 2, "name": "styles-typed-endnotes", "sha256": "6d498bd40c567687854fc08323959a02b2d0e9fc5cd6eaa0d02211095842df36", "observedAt": "2026-10-26T18:37:26+00:00", "staged": "00004__wfv__styles-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:37:25.650 'Word found unreadable content in 00004__wfv__styles-typed-endnotes.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-26 14:37:26.154 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00004__wfv__styles-typed-endnotes.docx)\""]}
{"run": "s59a", "pass": 1, "name": "numbering-typed-footnotes", "sha256": "ef3014c3f6965070c5d826fc17c32679b62322563348d7e969875a6d7ba48dbb", "observedAt": "2026-10-26T18:37:01+00:00", "staged": "00001__wfv__numbering-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:36:56.475 Microsoft Word, Word found unreadable content in 00001__wfv__numbering-typed-footnotes.docx. Do you  … t? If you trust the source of this document, click Yes."]}
{"run": "s59a", "pass": 2, "name": "numbering-typed-footnotes", "sha256": "ef3014c3f6965070c5d826fc17c32679b62322563348d7e969875a6d7ba48dbb", "observedAt": "2026-10-26T18:37:26+00:00", "staged": "00001__wfv__numbering-typed-footnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:37:21.299 'Word found unreadable content in 00001__wfv__numbering-typed-footnotes.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 14:37:22.087 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__numbering-typed-footnotes...)\""]}
{"run": "s59a", "pass": 1, "name": "numbering-typed-endnotes", "sha256": "6ef55472e769e130355256bbba58dfc04a7027531553752677cb97516d0f0fb2", "observedAt": "2026-10-26T18:37:01+00:00", "staged": "00000__wfv__numbering-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:36:04.021 \"Word found unreadable content in 00000__wfv__numbering-typed-endnotes.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s59a", "pass": 2, "name": "numbering-typed-endnotes", "sha256": "6ef55472e769e130355256bbba58dfc04a7027531553752677cb97516d0f0fb2", "observedAt": "2026-10-26T18:37:26+00:00", "staged": "00000__wfv__numbering-typed-endnotes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 14:37:17.104 'Word found unreadable content in 00000__wfv__numbering-typed-endnotes.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-26 14:37:17.867 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__numbering-typed-endnotes....)\""]}
{"run": "s59a", "pass": 1, "name": "s59a-control-minimal-end", "sha256": "4a1ff3c351b0a83cb04cd74be12baf1a81cf5fb2e039369b51de6747e0afcc08", "observedAt": "2026-10-26T18:37:01+00:00", "staged": "00002__wfv__s59a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s59a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s59a", "pass": 2, "name": "s59a-control-minimal-end", "sha256": "4a1ff3c351b0a83cb04cd74be12baf1a81cf5fb2e039369b51de6747e0afcc08", "observedAt": "2026-10-26T18:37:26+00:00", "staged": "00002__wfv__s59a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s59a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 59 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s59builder.mts`:

```ts
// Session 59 (2026-10-26): the three eager mapped-type pairs no session has shown (#779's residue). Lane 778 keyed every
// mismatch recovery sentence by (reach, declared type) and found three pairs with no Word row in sessions 49, 50, 53, 56
// or 57: word/styles.xml typed by its Override with the endnotes type, and a related word/numbering.xml typed with the
// footnotes or endnotes type. word-valid blocks all three with no recovery sentence; this session asks Word.
// Helpers are copied verbatim from s57builder.mts (relatedTyped, stylesRetyped).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s59a pnpm exec node --import tsx s59builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const STYLES_TYPE = `${WML}.styles+xml`;
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const retype = (ct: string, part: string, own: string, type: string) =>
    replaceOnce(ct, `<Override PartName="/${part}" ContentType="${own}"/>`, `<Override PartName="/${part}" ContentType="${type}"/>`);
const control = () => buildDocx({ ...P });

const NUMBERING_ROOT = `${XML_DECL}<w:numbering xmlns:w="${W}"/>`;
const TYPES = {
    footnotes: `${WML}.footnotes+xml`,
    endnotes: `${WML}.endnotes+xml`,
};

/** The minimal package plus `word/numbering.xml` related from the main document's sidecar as rId2, typed `type` (sessions 50, 53, 57). */
const numberingTyped = (type: string) =>
    buildDocx({
        ...P,
        "word/numbering.xml": NUMBERING_ROOT,
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rId2", "numbering", "numbering.xml")),
        [CT]: overrides(P[CT]!, ["word/numbering.xml", type]),
    });
const stylesRetyped = (type: string) => buildDocx({ ...P, [CT]: retype(P[CT]!, "word/styles.xml", STYLES_TYPE, type) });

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const pair = (reach: string, type: keyof typeof TYPES): string =>
    `#779 residue: the ${reach} typed by its Override with the ${type} content type`;

const chunks: Record<string, Row[]> = {
    s59a: withControls("s59a", [
        ["styles-typed-endnotes", pair("word/styles.xml", "endnotes"), () => stylesRetyped(TYPES.endnotes)],
        ["numbering-typed-footnotes", pair("related word/numbering.xml", "footnotes"), () => numberingTyped(TYPES.footnotes)],
        ["numbering-typed-endnotes", pair("related word/numbering.xml", "endnotes"), () => numberingTyped(TYPES.endnotes)],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-59 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s59a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s59/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-59 parts of docs/plans/evidence/word-probes-2026-10-24.md into s59/section.md.

Reads the chunk's specimens.jsonl (validator columns at bfb8eb75, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s59/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s59a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s59/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 59: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at bfb8eb75",
    "",
    "The three eager mapped-type pairs no session had shown "
    "([#779](https://github.com/jandira-tech/docx-validate/issues/779)). Keying each mismatch recovery sentence by its pair left "
    "`word/styles.xml` typed endnotes, and a related `word/numbering.xml` typed footnotes or endnotes, with no Word row in "
    "sessions 49, 50, 53, 56 or 57. One chunk, opening and closing with the minimal control. It ran twice, as two separate driver "
    "runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    f"`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    "builder's description of the specimen.",
    "",
    "- All three pairs get the recovery offer, as every other eager pair did. Word-valid at bfb8eb75 already rejects all three, "
    "so no verdict changes; these rows are the observation their findings' recovery sentences lacked.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at bfb8eb75 | strict at bfb8eb75 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 59</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 59 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s59builder.mts", ROOT / "s59builder.mts", "ts"), ("compare.py", ROOT / "s59/compare.py", "python"),
                         ("section.py", ROOT / "s59/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s59/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 60: 18:51Z–18:51Z on 2026-10-26, validator columns at 04ec2f08

Notes parts stored under another name ([#793](https://github.com/jandira-tech/docx-validate/issues/793)). `word-footnote-reference-missing`, and since #784 `word-endnote-reference-missing`, collect the defined note ids only from parts named `footnotes.xml` or `endnotes.xml`, while references are read in every story part. One chunk, opening and closing with the minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 6 of 6 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A used footnotes part stored as `word/notes-foot.xml`, and a used endnotes part stored as `word/notes-end.xml`, each related by the main document's `footnotes` or `endnotes` relationship and holding the note the body references, open clean, as do the same parts stored under the standard names. Each renamed row's PDF is the same size as its calibration's (14684 bytes for footnotes, 14956 for endnotes). Word-valid at 04ec2f08 rejects both renamed rows: two false positives, the footnote one older than the stack and the endnote one introduced by #784's layer.

| Run    | Observed             | Specimen                              | Shape                                                                                                                              | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at 04ec2f08                     | strict at 04ec2f08                         |
| ------ | -------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ------------------------------------------ | ------------------------------------------ |
| `s60a` | 18:51:44Z, 18:51:56Z | `s60a-control-minimal`                | control                                                                                                                            | `965bbaebb2339172` | clean-open  | clean-open  | clean-open | valid                                      | valid                                      |
| `s60a` | 18:51:44Z, 18:51:56Z | `footnotes-renamed-matching`          | a used footnotes part stored as word/notes-foot.xml, related by the footnotes relationship, holding footnote 1 the body references | `25b8655b3ec6576d` | clean-open  | clean-open  | clean-open | invalid: `word-footnote-reference-missing` | invalid: `word-footnote-reference-missing` |
| `s60a` | 18:51:44Z, 18:51:56Z | `endnotes-renamed-matching`           | a used endnotes part stored as word/notes-end.xml, related by the endnotes relationship, holding endnote 1 the body references     | `330da54a65f28f77` | clean-open  | clean-open  | clean-open | invalid: `word-endnote-reference-missing`  | invalid: `word-endnote-reference-missing`  |
| `s60a` | 18:51:44Z, 18:51:56Z | `footnotes-standard-name-calibration` | calibration: the same footnotes part stored as word/footnotes.xml                                                                  | `a1461c67c75b8e15` | clean-open  | clean-open  | clean-open | valid                                      | invalid: `paraid-missing-element`          |
| `s60a` | 18:51:44Z, 18:51:56Z | `endnotes-standard-name-calibration`  | calibration: the same endnotes part stored as word/endnotes.xml                                                                    | `a5d891bab4e04d2c` | clean-open  | clean-open  | clean-open | valid                                      | invalid: `paraid-missing-element`          |
| `s60a` | 18:51:44Z, 18:51:56Z | `s60a-control-minimal-end`            | control                                                                                                                            | `965bbaebb2339172` | clean-open  | clean-open  | clean-open | valid                                      | valid                                      |

<details><summary>Raw records, session 60</summary>

```jsonl
{"run": "s60a", "pass": 1, "name": "s60a-control-minimal", "sha256": "965bbaebb2339172ec7072a1e9da3e0d8725690be9b1790bb55b303cc00a7fe4", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00005__wfv__s60a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s60a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "s60a-control-minimal", "sha256": "965bbaebb2339172ec7072a1e9da3e0d8725690be9b1790bb55b303cc00a7fe4", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00005__wfv__s60a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s60a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 1, "name": "footnotes-renamed-matching", "sha256": "25b8655b3ec6576dee326462683292a3107421dfc09ab10465be2fe53da5d199", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00002__wfv__footnotes-renamed-matching.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-renamed-matching_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "footnotes-renamed-matching", "sha256": "25b8655b3ec6576dee326462683292a3107421dfc09ab10465be2fe53da5d199", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00002__wfv__footnotes-renamed-matching.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-renamed-matching_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 1, "name": "endnotes-renamed-matching", "sha256": "330da54a65f28f779c50f65a3d2c3e814fe55741d4b7306260dee153140c64ce", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00000__wfv__endnotes-renamed-matching.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-renamed-matching_byword.pdf (14956 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "endnotes-renamed-matching", "sha256": "330da54a65f28f779c50f65a3d2c3e814fe55741d4b7306260dee153140c64ce", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00000__wfv__endnotes-renamed-matching.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-renamed-matching_byword.pdf (14956 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 1, "name": "footnotes-standard-name-calibration", "sha256": "a1461c67c75b8e150ff06412e1a8ec9646b97dbec355a119625286bf51c772b0", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00003__wfv__footnotes-standard-name-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-standard-name-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "footnotes-standard-name-calibration", "sha256": "a1461c67c75b8e150ff06412e1a8ec9646b97dbec355a119625286bf51c772b0", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00003__wfv__footnotes-standard-name-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-standard-name-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 1, "name": "endnotes-standard-name-calibration", "sha256": "a5d891bab4e04d2c214370c483b124f3b201e54912eea72c0d49dd6e978db739", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00001__wfv__endnotes-standard-name-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-standard-name-calibration_byword.pdf (14956 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "endnotes-standard-name-calibration", "sha256": "a5d891bab4e04d2c214370c483b124f3b201e54912eea72c0d49dd6e978db739", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00001__wfv__endnotes-standard-name-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-standard-name-calibration_byword.pdf (14956 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 1, "name": "s60a-control-minimal-end", "sha256": "965bbaebb2339172ec7072a1e9da3e0d8725690be9b1790bb55b303cc00a7fe4", "observedAt": "2026-10-26T18:51:44+00:00", "staged": "00004__wfv__s60a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s60a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s60a", "pass": 2, "name": "s60a-control-minimal-end", "sha256": "965bbaebb2339172ec7072a1e9da3e0d8725690be9b1790bb55b303cc00a7fe4", "observedAt": "2026-10-26T18:51:56+00:00", "staged": "00004__wfv__s60a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s60a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 60 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s60builder.mts`:

```ts
// Session 60 (2026-10-26): note parts stored under another name. word-footnote-reference-missing finds the defined
// footnotes by part basename (`footnotes.xml`), and lane 784's word-endnote-reference-missing does the same for
// `endnotes.xml`, while references are read in every story part. A footnotes or endnotes part the main document
// relates under another name, holding the id the body references, is judged dangling by name. This session asks Word
// whether it opens such a package clean (as relationship-based reading predicts), with the standard names as
// calibrations.
// Helpers are copied from s57builder.mts (mainWith, relationship, appendRels, overrides).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s60a pnpm exec node --import tsx s60builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });
/** `parts` with `run` appended inside the main document's only paragraph. */
const mainWith = (parts: Record<string, string>, run: string): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(parts[MAIN]!, "</w:r></w:p>", `</w:r>${run}</w:p>`),
});

type Kind = "footnote" | "endnote";
const NOTE_P = "<w:p><w:r><w:t>Note</w:t></w:r></w:p>";
/** A used notes part holding note 1, stored at `word/<name>` and related as rIdN; the body references note 1. */
const notesAt = (kind: Kind, name: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${name}`]: `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="1">${NOTE_P}</w:${kind}></w:${kind}s>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, name)),
                [CT]: overrides(P[CT]!, [`word/${name}`, `${WML}.${kind}s+xml`]),
            },
            `<w:r><w:${kind}Reference w:id="1"/></w:r>`,
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s60a: withControls("s60a", [
        [
            "footnotes-renamed-matching",
            "a used footnotes part stored as word/notes-foot.xml, related by the footnotes relationship, holding footnote 1 the body references",
            () => notesAt("footnote", "notes-foot.xml"),
        ],
        [
            "endnotes-renamed-matching",
            "a used endnotes part stored as word/notes-end.xml, related by the endnotes relationship, holding endnote 1 the body references",
            () => notesAt("endnote", "notes-end.xml"),
        ],
        [
            "footnotes-standard-name-calibration",
            "calibration: the same footnotes part stored as word/footnotes.xml",
            () => notesAt("footnote", "footnotes.xml"),
        ],
        [
            "endnotes-standard-name-calibration",
            "calibration: the same endnotes part stored as word/endnotes.xml",
            () => notesAt("endnote", "endnotes.xml"),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-60 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s60a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s60/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-60 parts of docs/plans/evidence/word-probes-2026-10-24.md into s60/section.md.

Reads the chunk's specimens.jsonl (validator columns at 04ec2f08, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s60/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s60a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s60/results.json").read_text())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 60: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at 04ec2f08",
    "",
    "Notes parts stored under another name "
    "([#793](https://github.com/jandira-tech/docx-validate/issues/793)). `word-footnote-reference-missing`, and since #784 "
    "`word-endnote-reference-missing`, collect the defined note ids only from parts named `footnotes.xml` or `endnotes.xml`, "
    "while references are read in every story part. One chunk, opening and closing with the minimal control. It ran twice, as two "
    "separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    f"`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and "
    f"`unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen.",
    "",
    "- A used footnotes part stored as `word/notes-foot.xml`, and a used endnotes part stored as `word/notes-end.xml`, each related "
    "by the main document's `footnotes` or `endnotes` relationship and holding the note the body references, open clean, as do "
    "the same parts stored under the standard names. Each renamed row's PDF is the same size as its calibration's (14684 bytes "
    "for footnotes, 14956 for endnotes). Word-valid at 04ec2f08 rejects both renamed rows: two false positives, the footnote one "
    "older than the stack and the endnote one introduced by #784's layer.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at 04ec2f08 | strict at 04ec2f08 |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 60</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 60 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s60builder.mts", ROOT / "s60builder.mts", "ts"), ("compare.py", ROOT / "s60/compare.py", "python"),
                         ("section.py", ROOT / "s60/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s60/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 61: 19:14Z–19:18Z on 2026-10-26, validator columns at f0d42f3d

The open question of [#793](https://github.com/jandira-tech/docx-validate/issues/793): whether a notes part named `footnotes.xml` or `endnotes.xml` that no relationship names defines the note the body references. After #793 the note checks collect definitions from those names as well as from the parts a `footnotes` or `endnotes` relationship names. Two chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 10 of 10 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.

- A `word/footnotes.xml` or `word/endnotes.xml` holding note 1, typed by its Override but named by no relationship, gets the recovery offer when the body references note 1, and so does the same part beside a related renamed part that holds note 5. Word-valid at f0d42f3d accepts all four: four false negatives, from the name-based definitions.
- The same unrelated parts with nothing referencing them open clean (s61b), so the refusals come from the dangling reference, not from the unrelated part: Word defines notes only from the parts their relationships name.

| Run    | Observed             | Specimen                                                     | Shape                                                                                                                                                               | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f0d42f3d | strict at f0d42f3d                                     |
| ------ | -------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | ------------------------------------------------------ |
| `s61a` | 19:14:09Z, 19:17:30Z | `s61a-control-minimal`                                       | control                                                                                                                                                             | `4b8082cd2501ebde` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                  |
| `s61a` | 19:14:09Z, 19:17:30Z | `footnotes-unrelated-standard-name`                          | #793: word/footnotes.xml holding footnote 1, typed by its Override, named by no relationship; the body references footnote 1                                        | `cfbc6f977786af24` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61a` | 19:14:09Z, 19:17:30Z | `endnotes-unrelated-standard-name`                           | #793: word/endnotes.xml holding endnote 1, typed by its Override, named by no relationship; the body references endnote 1                                           | `92c61408cd64848a` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61a` | 19:14:09Z, 19:17:30Z | `footnotes-related-other-id-plus-unrelated-standard`         | #793: the footnotes relationship names word/notes-foot.xml holding footnote 5, and an unrelated word/footnotes.xml holds footnote 1; the body references footnote 1 | `92decd70f9265394` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61a` | 19:14:09Z, 19:17:30Z | `endnotes-related-other-id-plus-unrelated-standard`          | #793: the endnotes relationship names word/notes-end.xml holding endnote 5, and an unrelated word/endnotes.xml holds endnote 1; the body references endnote 1       | `ce93ce3b0347b1d1` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61a` | 19:14:09Z, 19:17:30Z | `s61a-control-minimal-end`                                   | control                                                                                                                                                             | `4b8082cd2501ebde` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                  |
| `s61b` | 19:18:16Z, 19:18:30Z | `s61b-control-minimal`                                       | control                                                                                                                                                             | `7ca654a6991f57f1` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                  |
| `s61b` | 19:18:16Z, 19:18:30Z | `footnotes-unrelated-standard-name-no-reference-calibration` | calibration: the unrelated word/footnotes.xml of s61a, with no footnote reference in the body                                                                       | `1295d80d03ec2549` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61b` | 19:18:16Z, 19:18:30Z | `endnotes-unrelated-standard-name-no-reference-calibration`  | calibration: the unrelated word/endnotes.xml of s61a, with no endnote reference in the body                                                                         | `d6154c8c9d53dd3c` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element` |
| `s61b` | 19:18:16Z, 19:18:30Z | `s61b-control-minimal-end`                                   | control                                                                                                                                                             | `7ca654a6991f57f1` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                  |

<details><summary>Raw records, session 61</summary>

```jsonl
{"run": "s61a", "pass": 1, "name": "s61a-control-minimal", "sha256": "4b8082cd2501ebde01700cef89bc69970675a595d8721313e1f90f5317b97140", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00005__wfv__s61a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61a", "pass": 2, "name": "s61a-control-minimal", "sha256": "4b8082cd2501ebde01700cef89bc69970675a595d8721313e1f90f5317b97140", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00005__wfv__s61a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61a", "pass": 1, "name": "footnotes-unrelated-standard-name", "sha256": "cfbc6f977786af2496549fee4bfd6522915c5f22298cfa04e567fded052f5a48", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00003__wfv__footnotes-unrelated-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:12:46.887 'Word found unreadable content in 00003__wfv__footnotes-unrelated-standard-name.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:12:47.700 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__footnotes-unrelated-stand...)\""]}
{"run": "s61a", "pass": 2, "name": "footnotes-unrelated-standard-name", "sha256": "cfbc6f977786af2496549fee4bfd6522915c5f22298cfa04e567fded052f5a48", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00003__wfv__footnotes-unrelated-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:16:20.445 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00003__wfv__footnotes-unrelated-stand...)'", "2026-10-26 15:17:29.452 'Word found unreadable content in 00003__wfv__footnotes-unrelated-standard-name.docx. Do you want to … ? If you trust the source of this document, click Yes.'"]}
{"run": "s61a", "pass": 1, "name": "endnotes-unrelated-standard-name", "sha256": "92c61408cd64848aeb63bc20351af05543746227af5d81de02d6326e48715030", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00001__wfv__endnotes-unrelated-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:12:38.506 'Word found unreadable content in 00001__wfv__endnotes-unrelated-standard-name.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:12:39.019 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__endnotes-unrelated-standa...)\""]}
{"run": "s61a", "pass": 2, "name": "endnotes-unrelated-standard-name", "sha256": "92c61408cd64848aeb63bc20351af05543746227af5d81de02d6326e48715030", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00001__wfv__endnotes-unrelated-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:15:14.412 'Word found unreadable content in 00001__wfv__endnotes-unrelated-standard-name.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:15:14.970 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__endnotes-unrelated-standa...)\""]}
{"run": "s61a", "pass": 1, "name": "footnotes-related-other-id-plus-unrelated-standard", "sha256": "92decd70f9265394e3b1633f83285ecccf535df465b184542ff43312d5b7ecbf", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00002__wfv__footnotes-related-other-id-plus-unrelated-standard.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:12:42.735 'Word found unreadable content in 00002__wfv__footnotes-related-other-id-plus-unrelated-standa.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:12:43.551 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__footnotes-related-other-i...)\""]}
{"run": "s61a", "pass": 2, "name": "footnotes-related-other-id-plus-unrelated-standard", "sha256": "92decd70f9265394e3b1633f83285ecccf535df465b184542ff43312d5b7ecbf", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00002__wfv__footnotes-related-other-id-plus-unrelated-standard.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:16:03.001 Microsoft Word, Word found unreadable content in 00002__wfv__footnotes-related-other-id-plus-unrelat … t? If you trust the source of this document, click Yes.", "2026-10-26 15:16:03.736 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__footnotes-related-other-i...)\""]}
{"run": "s61a", "pass": 1, "name": "endnotes-related-other-id-plus-unrelated-standard", "sha256": "ce93ce3b0347b1d1d1b55e1a3b05b111fc6b0ce5222157e63f70d0d5d6b61d12", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00000__wfv__endnotes-related-other-id-plus-unrelated-standard.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:12:33.963 'Word found unreadable content in 00000__wfv__endnotes-related-other-id-plus-unrelated-standar.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:12:34.551 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__endnotes-related-other-id...)\""]}
{"run": "s61a", "pass": 2, "name": "endnotes-related-other-id-plus-unrelated-standard", "sha256": "ce93ce3b0347b1d1d1b55e1a3b05b111fc6b0ce5222157e63f70d0d5d6b61d12", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00000__wfv__endnotes-related-other-id-plus-unrelated-standard.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:14:26.019 'Word found unreadable content in 00000__wfv__endnotes-related-other-id-plus-unrelated-standar.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:14:26.588 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__endnotes-related-other-id...)\""]}
{"run": "s61a", "pass": 1, "name": "s61a-control-minimal-end", "sha256": "4b8082cd2501ebde01700cef89bc69970675a595d8721313e1f90f5317b97140", "observedAt": "2026-10-26T19:14:09+00:00", "staged": "00004__wfv__s61a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61a", "pass": 2, "name": "s61a-control-minimal-end", "sha256": "4b8082cd2501ebde01700cef89bc69970675a595d8721313e1f90f5317b97140", "observedAt": "2026-10-26T19:17:30+00:00", "staged": "00004__wfv__s61a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 1, "name": "s61b-control-minimal", "sha256": "7ca654a6991f57f145cc5829ddd72abf7ebcff448ce81334e3d9fae877ce5326", "observedAt": "2026-10-26T19:18:16+00:00", "staged": "00003__wfv__s61b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 2, "name": "s61b-control-minimal", "sha256": "7ca654a6991f57f145cc5829ddd72abf7ebcff448ce81334e3d9fae877ce5326", "observedAt": "2026-10-26T19:18:30+00:00", "staged": "00003__wfv__s61b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 1, "name": "footnotes-unrelated-standard-name-no-reference-calibration", "sha256": "1295d80d03ec25496f2f1cf7850a3aa3cd0031f4ed94c2aa6ce5593f49e716ec", "observedAt": "2026-10-26T19:18:16+00:00", "staged": "00001__wfv__footnotes-unrelated-standard-name-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-unrelated-standard-name-no-reference-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 2, "name": "footnotes-unrelated-standard-name-no-reference-calibration", "sha256": "1295d80d03ec25496f2f1cf7850a3aa3cd0031f4ed94c2aa6ce5593f49e716ec", "observedAt": "2026-10-26T19:18:30+00:00", "staged": "00001__wfv__footnotes-unrelated-standard-name-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-unrelated-standard-name-no-reference-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 1, "name": "endnotes-unrelated-standard-name-no-reference-calibration", "sha256": "d6154c8c9d53dd3ce51415bb85249e45a0b90e30ccb5d3c867c47174d3723fff", "observedAt": "2026-10-26T19:18:16+00:00", "staged": "00000__wfv__endnotes-unrelated-standard-name-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-unrelated-standard-name-no-reference-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 2, "name": "endnotes-unrelated-standard-name-no-reference-calibration", "sha256": "d6154c8c9d53dd3ce51415bb85249e45a0b90e30ccb5d3c867c47174d3723fff", "observedAt": "2026-10-26T19:18:30+00:00", "staged": "00000__wfv__endnotes-unrelated-standard-name-no-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-unrelated-standard-name-no-reference-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 1, "name": "s61b-control-minimal-end", "sha256": "7ca654a6991f57f145cc5829ddd72abf7ebcff448ce81334e3d9fae877ce5326", "observedAt": "2026-10-26T19:18:16+00:00", "staged": "00002__wfv__s61b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s61b", "pass": 2, "name": "s61b-control-minimal-end", "sha256": "7ca654a6991f57f145cc5829ddd72abf7ebcff448ce81334e3d9fae877ce5326", "observedAt": "2026-10-26T19:18:30+00:00", "staged": "00002__wfv__s61b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s61b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 61 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s61builder.mts`:

```ts
// Session 61 (2026-10-26): the open question of #793. The note checks still collect definitions from any part named
// `footnotes.xml` / `endnotes.xml`, related or not, beside the parts a footnotes/endnotes relationship names. This
// session asks Word whether a standard-named notes part that no relationship names defines the note the body references:
// alone (no notes relationship at all), and beside a related renamed part that holds another id. Chunk s61b
// calibrates: the same unrelated parts with nothing referencing them.
// Helpers are copied from s60builder.mts.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s61a pnpm exec node --import tsx s61builder.tmp.mts
import { createHash } from "node:crypto";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });
/** `parts` with `run` appended inside the main document's only paragraph. */
const mainWith = (parts: Record<string, string>, run: string): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(parts[MAIN]!, "</w:r></w:p>", `</w:r>${run}</w:p>`),
});

type Kind = "footnote" | "endnote";
const NOTE_P = "<w:p><w:r><w:t>Note</w:t></w:r></w:p>";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${NOTE_P}</w:${kind}></w:${kind}s>`;
const reference = (kind: Kind) => `<w:r><w:${kind}Reference w:id="1"/></w:r>`;

/** word/<kind>s.xml holding note 1, typed by its Override, but named by no relationship; the body references note 1. */
const unrelatedStandard = (kind: Kind) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${kind}s.xml`]: notesXml(kind, "1"),
                [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, `${WML}.${kind}s+xml`]),
            },
            reference(kind),
        ),
    );

/** A related word/<renamed> holding note 5, plus an unrelated word/<kind>s.xml holding note 1; the body references note 1. */
const relatedOtherIdPlusUnrelatedStandard = (kind: Kind, renamed: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [`word/${renamed}`]: notesXml(kind, "5"),
                [`word/${kind}s.xml`]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, renamed)),
                [CT]: overrides(P[CT]!, [`word/${renamed}`, `${WML}.${kind}s+xml`], [`word/${kind}s.xml`, `${WML}.${kind}s+xml`]),
            },
            reference(kind),
        ),
    );

/** The same unrelated word/<kind>s.xml holding note 1, typed by its Override, with nothing in the body referencing it. */
const unrelatedStandardNoReference = (kind: Kind) =>
    buildDocx({
        ...P,
        [`word/${kind}s.xml`]: notesXml(kind, "1"),
        [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, `${WML}.${kind}s+xml`]),
    });

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s61a: withControls("s61a", [
        [
            "footnotes-unrelated-standard-name",
            "#793: word/footnotes.xml holding footnote 1, typed by its Override, named by no relationship; the body references footnote 1",
            () => unrelatedStandard("footnote"),
        ],
        [
            "endnotes-unrelated-standard-name",
            "#793: word/endnotes.xml holding endnote 1, typed by its Override, named by no relationship; the body references endnote 1",
            () => unrelatedStandard("endnote"),
        ],
        [
            "footnotes-related-other-id-plus-unrelated-standard",
            "#793: the footnotes relationship names word/notes-foot.xml holding footnote 5, and an unrelated word/footnotes.xml holds footnote 1; the body references footnote 1",
            () => relatedOtherIdPlusUnrelatedStandard("footnote", "notes-foot.xml"),
        ],
        [
            "endnotes-related-other-id-plus-unrelated-standard",
            "#793: the endnotes relationship names word/notes-end.xml holding endnote 5, and an unrelated word/endnotes.xml holds endnote 1; the body references endnote 1",
            () => relatedOtherIdPlusUnrelatedStandard("endnote", "notes-end.xml"),
        ],
    ]),
    s61b: withControls("s61b", [
        [
            "footnotes-unrelated-standard-name-no-reference-calibration",
            "calibration: the unrelated word/footnotes.xml of s61a, with no footnote reference in the body",
            () => unrelatedStandardNoReference("footnote"),
        ],
        [
            "endnotes-unrelated-standard-name-no-reference-calibration",
            "calibration: the unrelated word/endnotes.xml of s61a, with no endnote reference in the body",
            () => unrelatedStandardNoReference("endnote"),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-61 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s61a", "s61b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s61/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-61 parts of docs/plans/evidence/word-probes-2026-10-24.md into s61/section.md.

Reads the chunk's specimens.jsonl (validator columns at f0d42f3d, written by the builder), both runs'
logcheck.jsonl and pdf/manifest.jsonl, and s61/results.json from compare.py.
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s61a", "s61b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s61/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends = [], [], [], []
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
                                   "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

out = [
    f"### Session 61: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at f0d42f3d",
    "",
    "The open question of [#793](https://github.com/jandira-tech/docx-validate/issues/793): whether a notes part named "
    "`footnotes.xml` or `endnotes.xml` that no relationship names defines the note the body references. After #793 the note checks "
    "collect definitions from those names as well as from the parts a `footnotes` or `endnotes` relationship names. Two chunks, "
    "each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and "
    "each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    f"is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. "
    "The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen.",
    "",
    "- A `word/footnotes.xml` or `word/endnotes.xml` holding note 1, typed by its Override but named by no relationship, gets "
    "the recovery offer when the body references note 1, and so does the same part beside a related renamed part that holds "
    "note 5. Word-valid at f0d42f3d accepts all four: four false negatives, from the name-based definitions.",
    "- The same unrelated parts with nothing referencing them open clean (s61b), so the refusals come from the dangling "
    "reference, not from the unrelated part: Word defines notes only from the parts their relationships name.",
    "",
    "| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at f0d42f3d | strict at f0d42f3d |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 61</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 61 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s61builder.mts", ROOT / "s61builder.mts", "ts"), ("compare.py", ROOT / "s61/compare.py", "python"),
                         ("section.py", ROOT / "s61/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s61/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 62: 19:51Z–20:06Z on 2026-10-26, validator columns at 0b09054c

The Word questions the adversarial review of layers 188–191 left open: comment markers and definitions in an unselected `mc:Choice` ([#799](https://github.com/jandira-tech/docx-validate/issues/799)), a renamed main document's note references and an unrelated story-named header ([#800](https://github.com/jandira-tech/docx-validate/issues/800)), note ids spelled `01` or `+1` ([#801](https://github.com/jandira-tech/docx-validate/issues/801)), comments and notes parts typed styles with a charset parameter ([#802](https://github.com/jandira-tech/docx-validate/issues/802)), a second endnotes relationship, and dangling note references in a read header. Chunk s62e was added after s62c and s62d ran, to separate s62c's second-relationship refusals and to ask s62d's header question for footnotes. Five chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 35 of 36 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`0b09054c3a9836d5bd5498e499a8f91fe6fca67a`).

- **#799 (s62a).** A `w:commentReference` that exists only in an unselected Choice opens clean, while word-valid rejects it (`comment-marker-missing`): a false positive. A body reference whose comment exists only in an unselected Choice of the comments part gets the recovery offer, while word-valid accepts it: a false negative. The same comments part with the Choice requiring `w14` opens clean, so Word does process `mc:AlternateContent` among the comments and selects by `Requires`.
- **#800 (s62a, s62d).** With the main document stored as `word/main.xml`, a dangling endnote or footnote reference gets the recovery offer and the matching calibration opens clean; word-valid accepts both dangling rows: two false negatives. An unrelated `word/header9.xml` holding a dangling footnote reference opens clean (its PDF is the control's size), while word-valid rejects it: a false positive.
- **#801 (s62b).** References spelled `01` or `+1` to a note spelled `1` open clean for both kinds, each PDF the size of its canonical calibration's, so Word compares ids as integers; word-valid rejects all four: four false positives.
- **#802 (s62c).** Used comments, endnotes and footnotes parts typed `styles+xml; charset=utf-8` get the recovery offer, and word-valid accepts all three: three false negatives. The comments part typed with its own type plus the parameter was refused in the second run and raised a save prompt in the first, so its outcome is `unknown`.
- **Two endnotes relationships (s62c, s62e).** When the body references an endnote and the main document has two `endnotes` relationships, Word offers recovery whichever part holds the note, both included, and whether the second part is typed endnotes or `application/octet-stream`; the same two relationships with no endnote reference open clean. Word-valid accepts all four refused rows: four false negatives.
- **Note references in a read header (s62d, s62e).** A header the section references, holding a reference to endnote 1 or footnote 1 that the related notes part does not hold, opens clean, its PDF the size of the matching calibration's; word-valid rejects both: two false positives.

| Run    | Observed             | Specimen                                            | Shape                                                                                                                                                                                                         | SHA-256 (first 16) | Word, run 1                     | Word, run 2    | Outcome                    | word-valid at 0b09054c                     | strict at 0b09054c                                                                                    |
| ------ | -------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------------- | -------------- | -------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| `s62a` | 19:51:48Z, 19:53:29Z | `s62a-control-minimal`                              | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62a` | 19:51:48Z, 19:53:29Z | `comment-reference-only-in-unselected-choice`       | #799: word/comments.xml holds comment 5; the body's only w:commentReference (id 0) sits in mc:Choice Requires="u" (u not understood), the Fallback a text run                                                 | `8258434497e25f45` | clean-open                      | clean-open     | clean-open                 | invalid: `comment-marker-missing`          | invalid: `comment-marker-missing`, `comment-thread-count-mismatch`, `paraid-missing-element`          |
| `s62a` | 19:51:48Z, 19:53:29Z | `comment-definition-only-in-unselected-choice`      | #799: the body references comment 0; word/comments.xml holds comment 0 only in mc:Choice Requires="u" and comment 5 in the Fallback                                                                           | `d7ec2ac4f31327d5` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                    |
| `s62a` | 19:51:48Z, 19:53:29Z | `comment-definition-in-selected-choice-calibration` | #799 calibration: the same, the Choice requiring w14 (understood), so comment 0 is selected                                                                                                                   | `5c162308baf6cfd8` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                    |
| `s62a` | 19:51:48Z, 19:53:29Z | `renamed-main-dangling-endnote`                     | #800: main document stored as word/main.xml (officeDocument target, Override, sidecar renamed); the related word/endnotes.xml holds endnote 5; the body references endnote 1                                  | `63b292f320703864` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62a` | 19:51:48Z, 19:53:29Z | `renamed-main-dangling-footnote`                    | #800: the same for footnotes (word/footnotes.xml holds footnote 5; the body references footnote 1)                                                                                                            | `63895854893ad43d` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62a` | 19:51:48Z, 19:53:29Z | `renamed-main-matching-endnote-calibration`         | #800 calibration: main document word/main.xml; the related word/endnotes.xml holds endnote 1; the body references endnote 1                                                                                   | `09818dfe177ae5d6` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62a` | 19:51:48Z, 19:53:29Z | `s62a-control-minimal-end`                          | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62b` | 19:53:40Z, 19:53:53Z | `s62b-control-minimal`                              | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62b` | 19:53:40Z, 19:53:53Z | `footnote-reference-01-note-1`                      | #801: the related word/footnotes.xml holds footnote 1; the body's reference spells w:id="01"                                                                                                                  | `9e157340f50a576a` | clean-open                      | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `word-footnote-reference-missing`                                  |
| `s62b` | 19:53:40Z, 19:53:53Z | `endnote-reference-01-note-1`                       | #801: the same for endnotes                                                                                                                                                                                   | `95e5164d2b109968` | clean-open                      | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `paraid-missing-element`, `word-endnote-reference-missing`                                   |
| `s62b` | 19:53:40Z, 19:53:53Z | `footnote-reference-plus1-note-1`                   | #801: the related word/footnotes.xml holds footnote 1; the body's reference spells w:id="+1"                                                                                                                  | `57bba60a682dce3f` | clean-open                      | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `word-footnote-reference-missing`                                  |
| `s62b` | 19:53:40Z, 19:53:53Z | `endnote-reference-plus1-note-1`                    | #801: the same for endnotes                                                                                                                                                                                   | `aed1f6e7e7c7e994` | clean-open                      | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `paraid-missing-element`, `word-endnote-reference-missing`                                   |
| `s62b` | 19:53:40Z, 19:53:53Z | `footnote-reference-01-note-01-calibration`         | #801 calibration: footnote and reference both spell w:id="01"                                                                                                                                                 | `86a3fb9f827c527d` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62b` | 19:53:40Z, 19:53:53Z | `endnote-reference-plus1-note-plus1-calibration`    | #801 calibration: endnote and reference both spell w:id="+1"                                                                                                                                                  | `69bdbbcb27a77858` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62b` | 19:53:40Z, 19:53:53Z | `s62b-control-minimal-end`                          | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62c` | 20:01:03Z, 20:02:35Z | `s62c-control-minimal`                              | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62c` | 20:01:03Z, 20:02:35Z | `comments-typed-styles-charset`                     | #802: a used word/comments.xml (own root, comment 0, referenced) typed styles+xml; charset=utf-8                                                                                                              | `d20984baf343f9ac` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element` |
| `s62c` | 20:01:03Z, 20:02:35Z | `endnotes-typed-styles-charset`                     | #802: a used word/endnotes.xml (own root, endnote 1, referenced) typed styles+xml; charset=utf-8                                                                                                              | `eb3f8c8c3eab53e7` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                  |
| `s62c` | 20:01:03Z, 20:02:35Z | `footnotes-typed-styles-charset`                    | #802: a used word/footnotes.xml (own root, footnote 1, referenced) typed styles+xml; charset=utf-8                                                                                                            | `1920ac03a041ec06` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                                  |
| `s62c` | 20:01:03Z, 20:02:35Z | `comments-typed-comments-charset-calibration`       | #802 calibration: the same comments part typed comments+xml; charset=utf-8 (its own type with the parameter)                                                                                                  | `89067260a4cb064a` | log: other-dialog; table: other | repair-warning | unknown                    | invalid: `word-part-content-type-inexact`  | invalid: `word-part-content-type-inexact`, `comment-thread-count-mismatch`, `paraid-missing-element`  |
| `s62c` | 20:01:03Z, 20:02:35Z | `endnotes-second-relationship-octet-stream`         | review suspect: word/endnotes.xml (related) holds endnote 5; a second endnotes relationship names word/notes.bin, Override application/octet-stream, whose XML holds endnote 1; the body references endnote 1 | `af530628647d65f9` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-unrecognized`, `paraid-missing-element`                              |
| `s62c` | 20:01:03Z, 20:02:35Z | `endnotes-second-relationship-xml-calibration`      | review suspect calibration: the same with the second part word/notes2.xml typed endnotes+xml                                                                                                                  | `1f4452ca3d4e3b2f` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62c` | 20:01:03Z, 20:02:35Z | `s62c-control-minimal-end`                          | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62d` | 20:02:55Z, 20:03:11Z | `s62d-control-minimal`                              | control                                                                                                                                                                                                       | `ebce42a6e3d60aad` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62d` | 20:02:55Z, 20:03:11Z | `unrelated-header-dangling-footnote-reference`      | #800: word/header9.xml, typed header by its Override, named by no relationship, holds a w:footnoteReference to id 7; no footnotes part                                                                        | `15f10c7117ea3187` | clean-open                      | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-footnote-reference-missing`             |
| `s62d` | 20:02:55Z, 20:03:11Z | `read-header-dangling-endnote-reference`            | review source scope: a read header (word/header1.xml, referenced by the section) holds a reference to endnote 1; the related word/endnotes.xml holds endnote 5                                                | `a32503bf0278869a` | clean-open                      | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-endnote-reference-missing`         |
| `s62d` | 20:02:55Z, 20:03:11Z | `read-header-matching-endnote-calibration`          | calibration: the same with word/endnotes.xml holding endnote 1                                                                                                                                                | `3d6b5f2dc953f5ca` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`, `paraid-missing-element`                                           |
| `s62d` | 20:02:55Z, 20:03:11Z | `s62d-control-minimal-end`                          | control                                                                                                                                                                                                       | `b423b28fe6f52d8d` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62e` | 20:04:43Z, 20:06:08Z | `s62e-control-minimal`                              | control                                                                                                                                                                                                       | `2de9b5018b2187d1` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |
| `s62e` | 20:04:43Z, 20:06:08Z | `two-endnotes-relationships-first-holds-1`          | s62c follow-up: the first endnotes relationship names word/endnotes.xml holding endnote 1, a second names word/notes2.xml (endnotes+xml) holding endnote 5; the body references endnote 1                     | `d05cca283bacd509` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62e` | 20:04:43Z, 20:06:08Z | `two-endnotes-relationships-both-hold-1`            | s62c follow-up: the same with both parts holding endnote 1                                                                                                                                                    | `472ed10ae373be65` | repair-warning                  | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62e` | 20:04:43Z, 20:06:08Z | `two-endnotes-relationships-no-reference`           | s62c follow-up: word/endnotes.xml holds endnote 5, word/notes2.xml endnote 1, both related; nothing references an endnote                                                                                     | `dede60adb185335f` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                     |
| `s62e` | 20:04:43Z, 20:06:08Z | `read-header-dangling-footnote-reference`           | s62d follow-up: a read header holds a reference to footnote 1; the related word/footnotes.xml holds footnote 5                                                                                                | `75f113e806836f31` | clean-open                      | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing`        |
| `s62e` | 20:04:43Z, 20:06:08Z | `read-header-matching-footnote-calibration`         | calibration: the same with word/footnotes.xml holding footnote 1                                                                                                                                              | `a2227235b01b8a39` | clean-open                      | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`, `paraid-missing-element`                                           |
| `s62e` | 20:04:43Z, 20:06:08Z | `s62e-control-minimal-end`                          | control                                                                                                                                                                                                       | `2de9b5018b2187d1` | clean-open                      | clean-open     | clean-open                 | valid                                      | valid                                                                                                 |

<details><summary>Raw records, session 62</summary>

```jsonl
{"run": "s62a", "pass": 1, "name": "s62a-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00007__wfv__s62a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 2, "name": "s62a-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00007__wfv__s62a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 1, "name": "comment-reference-only-in-unselected-choice", "sha256": "8258434497e25f45e91473c99b084192f4bee418928f2f76efa5428d076c65e3", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00002__wfv__comment-reference-only-in-unselected-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-reference-only-in-unselected-choice_byword.pdf (13780 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 2, "name": "comment-reference-only-in-unselected-choice", "sha256": "8258434497e25f45e91473c99b084192f4bee418928f2f76efa5428d076c65e3", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00002__wfv__comment-reference-only-in-unselected-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-reference-only-in-unselected-choice_byword.pdf (13780 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 1, "name": "comment-definition-only-in-unselected-choice", "sha256": "d7ec2ac4f31327d568d6aeb17cd6f0476abad43ea843bcc6dbee0b72a47cd79f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00001__wfv__comment-definition-only-in-unselected-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:50:47.792 'Word found unreadable content in 00001__wfv__comment-definition-only-in-unselected-choice.docx. Do  … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:50:48.679 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comment-definition-only-i...)\""]}
{"run": "s62a", "pass": 2, "name": "comment-definition-only-in-unselected-choice", "sha256": "d7ec2ac4f31327d568d6aeb17cd6f0476abad43ea843bcc6dbee0b72a47cd79f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00001__wfv__comment-definition-only-in-unselected-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:52:20.177 'Word found unreadable content in 00001__wfv__comment-definition-only-in-unselected-choice.docx. Do  … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:52:21.130 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comment-definition-only-i...)\""]}
{"run": "s62a", "pass": 1, "name": "comment-definition-in-selected-choice-calibration", "sha256": "5c162308baf6cfd8f12aecab9ea39ca337f15b749eb713e0c308c233daf0ef6e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00000__wfv__comment-definition-in-selected-choice-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-definition-in-selected-choice-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 2, "name": "comment-definition-in-selected-choice-calibration", "sha256": "5c162308baf6cfd8f12aecab9ea39ca337f15b749eb713e0c308c233daf0ef6e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00000__wfv__comment-definition-in-selected-choice-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-definition-in-selected-choice-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 1, "name": "renamed-main-dangling-endnote", "sha256": "63b292f320703864824414e428e0b9ad0310bb933567e181f47d1b6dbcb9c3f2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00003__wfv__renamed-main-dangling-endnote.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:51:02.600 \"Word found unreadable content in 00003__wfv__renamed-main-dangling-endnote.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s62a", "pass": 2, "name": "renamed-main-dangling-endnote", "sha256": "63b292f320703864824414e428e0b9ad0310bb933567e181f47d1b6dbcb9c3f2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00003__wfv__renamed-main-dangling-endnote.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:52:35.340 \"Word found unreadable content in 00003__wfv__renamed-main-dangling-endnote.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s62a", "pass": 1, "name": "renamed-main-dangling-footnote", "sha256": "63895854893ad43d371c2c131924bc79e4b7491797cd8fe260188266352f39fd", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00004__wfv__renamed-main-dangling-footnote.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:51:47.159 Microsoft Word, Word found unreadable content in 00004__wfv__renamed-main-dangling-footnote.docx. Do … t? If you trust the source of this document, click Yes.", "2026-10-26 15:51:47.260 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__renamed-main-dangling-foo...)'"]}
{"run": "s62a", "pass": 2, "name": "renamed-main-dangling-footnote", "sha256": "63895854893ad43d371c2c131924bc79e4b7491797cd8fe260188266352f39fd", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00004__wfv__renamed-main-dangling-footnote.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:53:27.602 Microsoft Word, Word found unreadable content in 00004__wfv__renamed-main-dangling-footnote.docx. Do … t? If you trust the source of this document, click Yes.", "2026-10-26 15:53:28.338 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__renamed-main-dangling-foo...)\""]}
{"run": "s62a", "pass": 1, "name": "renamed-main-matching-endnote-calibration", "sha256": "09818dfe177ae5d6d6392077bb62a13ebe9389699303d44e535f16c1b7622f2f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00005__wfv__renamed-main-matching-endnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-main-matching-endnote-calibration_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 2, "name": "renamed-main-matching-endnote-calibration", "sha256": "09818dfe177ae5d6d6392077bb62a13ebe9389699303d44e535f16c1b7622f2f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00005__wfv__renamed-main-matching-endnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-main-matching-endnote-calibration_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 1, "name": "s62a-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:51:48+00:00", "staged": "00006__wfv__s62a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62a", "pass": 2, "name": "s62a-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:29+00:00", "staged": "00006__wfv__s62a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "s62b-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00007__wfv__s62b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "s62b-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00007__wfv__s62b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "footnote-reference-01-note-1", "sha256": "9e157340f50a576ac910038564637d78226b90d8e3dc40b9d812d117bc721a69", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00004__wfv__footnote-reference-01-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-01-note-1_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "footnote-reference-01-note-1", "sha256": "9e157340f50a576ac910038564637d78226b90d8e3dc40b9d812d117bc721a69", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00004__wfv__footnote-reference-01-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-01-note-1_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "endnote-reference-01-note-1", "sha256": "95e5164d2b1099680426e1f7fe647baf6b7d90d701cbf6e3f2d5861f607e7b5f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00000__wfv__endnote-reference-01-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-01-note-1_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "endnote-reference-01-note-1", "sha256": "95e5164d2b1099680426e1f7fe647baf6b7d90d701cbf6e3f2d5861f607e7b5f", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00000__wfv__endnote-reference-01-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-01-note-1_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "footnote-reference-plus1-note-1", "sha256": "57bba60a682dce3fbcbea5ed5d111309362feea6321aa533c63e6dcb039ce6a5", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00005__wfv__footnote-reference-plus1-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-plus1-note-1_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "footnote-reference-plus1-note-1", "sha256": "57bba60a682dce3fbcbea5ed5d111309362feea6321aa533c63e6dcb039ce6a5", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00005__wfv__footnote-reference-plus1-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-plus1-note-1_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "endnote-reference-plus1-note-1", "sha256": "aed1f6e7e7c7e9943b8ab45a2b4ac409e3f6a6c311394224dd84e51a57595a75", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00001__wfv__endnote-reference-plus1-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-plus1-note-1_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "endnote-reference-plus1-note-1", "sha256": "aed1f6e7e7c7e9943b8ab45a2b4ac409e3f6a6c311394224dd84e51a57595a75", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00001__wfv__endnote-reference-plus1-note-1.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-plus1-note-1_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "footnote-reference-01-note-01-calibration", "sha256": "86a3fb9f827c527de00cb0563a9d17a84c6137b19225ae8ab46fe84685b67b01", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00003__wfv__footnote-reference-01-note-01-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-01-note-01-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "footnote-reference-01-note-01-calibration", "sha256": "86a3fb9f827c527de00cb0563a9d17a84c6137b19225ae8ab46fe84685b67b01", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00003__wfv__footnote-reference-01-note-01-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-reference-01-note-01-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "endnote-reference-plus1-note-plus1-calibration", "sha256": "69bdbbcb27a778583c89307267391dd98f85d424329acdd0cd9fa8d5715055df", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00002__wfv__endnote-reference-plus1-note-plus1-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-plus1-note-plus1-calibration_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "endnote-reference-plus1-note-plus1-calibration", "sha256": "69bdbbcb27a778583c89307267391dd98f85d424329acdd0cd9fa8d5715055df", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00002__wfv__endnote-reference-plus1-note-plus1-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnote-reference-plus1-note-plus1-calibration_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 1, "name": "s62b-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:40+00:00", "staged": "00006__wfv__s62b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62b", "pass": 2, "name": "s62b-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T19:53:53+00:00", "staged": "00006__wfv__s62b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62c", "pass": 1, "name": "s62c-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00007__wfv__s62c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62c", "pass": 2, "name": "s62c-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00007__wfv__s62c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62c", "pass": 1, "name": "comments-typed-styles-charset", "sha256": "d20984baf343f9acf22e943297a3ede4cc5521441c9d4a38e36bfc0dde04a956", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00001__wfv__comments-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:59:21.468 \"Word found unreadable content in 00001__wfv__comments-typed-styles-charset.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s62c", "pass": 2, "name": "comments-typed-styles-charset", "sha256": "d20984baf343f9acf22e943297a3ede4cc5521441c9d4a38e36bfc0dde04a956", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00001__wfv__comments-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:02:17.079 Microsoft Word, Word found unreadable content in 00001__wfv__comments-typed-styles-charset.docx. Do  … t? If you trust the source of this document, click Yes."]}
{"run": "s62c", "pass": 1, "name": "endnotes-typed-styles-charset", "sha256": "eb3f8c8c3eab53e72739b194642e448f16735e7a43ae265f368a9296522773a6", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00004__wfv__endnotes-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:58:58.042 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__endnotes-typed-styles-cha...)'", "2026-10-26 16:01:02.854 'Word found unreadable content in 00004__wfv__endnotes-typed-styles-charset.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'"]}
{"run": "s62c", "pass": 2, "name": "endnotes-typed-styles-charset", "sha256": "eb3f8c8c3eab53e72739b194642e448f16735e7a43ae265f368a9296522773a6", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00004__wfv__endnotes-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:02:29.640 'Word found unreadable content in 00004__wfv__endnotes-typed-styles-charset.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:02:30.151 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__endnotes-typed-styles-cha...)\""]}
{"run": "s62c", "pass": 1, "name": "footnotes-typed-styles-charset", "sha256": "1920ac03a041ec06635bbc8f82d1ba55b76c4e406f934a8b391c76e40b8056f7", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00005__wfv__footnotes-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 15:59:02.259 'Word found unreadable content in 00005__wfv__footnotes-typed-styles-charset.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 15:59:02.873 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__footnotes-typed-styles-ch...)\""]}
{"run": "s62c", "pass": 2, "name": "footnotes-typed-styles-charset", "sha256": "1920ac03a041ec06635bbc8f82d1ba55b76c4e406f934a8b391c76e40b8056f7", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00005__wfv__footnotes-typed-styles-charset.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:02:33.807 'Word found unreadable content in 00005__wfv__footnotes-typed-styles-charset.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:02:34.319 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__footnotes-typed-styles-ch...)\""]}
{"run": "s62c", "pass": 1, "name": "comments-typed-comments-charset-calibration", "sha256": "89067260a4cb064aa488488609f52e4a5c818a02771695e1a84a4285f1a9c088", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00000__wfv__comments-typed-comments-charset-calibration.docx", "logVerdict": "other-dialog", "tableVerdict": "other", "pdf": false, "evidence": ["2026-10-26 15:58:49.456 'Want to save your changes to 00000__wfv__comments-typed-comments-charset-calibration.docx?'"]}
{"run": "s62c", "pass": 2, "name": "comments-typed-comments-charset-calibration", "sha256": "89067260a4cb064aa488488609f52e4a5c818a02771695e1a84a4285f1a9c088", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00000__wfv__comments-typed-comments-charset-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:01:24.390 'Word found unreadable content in 00000__wfv__comments-typed-comments-charset-calibration.docx. Do y … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:01:24.915 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-typed-comments-c...)\""]}
{"run": "s62c", "pass": 1, "name": "endnotes-second-relationship-octet-stream", "sha256": "af530628647d65f91cae47edc62b2587fef69df1e57f4331f7ef499a7c837e96", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00002__wfv__endnotes-second-relationship-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:00:11.308 Microsoft Word, Word found unreadable content in 00002__wfv__endnotes-second-relationship-octet-stre … t? If you trust the source of this document, click Yes."]}
{"run": "s62c", "pass": 2, "name": "endnotes-second-relationship-octet-stream", "sha256": "af530628647d65f91cae47edc62b2587fef69df1e57f4331f7ef499a7c837e96", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00002__wfv__endnotes-second-relationship-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:02:21.290 'Word found unreadable content in 00002__wfv__endnotes-second-relationship-octet-stream.docx. Do you … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:02:21.797 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__endnotes-second-relations...)\""]}
{"run": "s62c", "pass": 1, "name": "endnotes-second-relationship-xml-calibration", "sha256": "1f4452ca3d4e3b2fb23e9a1fc468092a99b8a0d6d19061665434b3eed4a45dd6", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00003__wfv__endnotes-second-relationship-xml-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:00:47.509 'Word found unreadable content in 00003__wfv__endnotes-second-relationship-xml-calibration.docx. Do  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s62c", "pass": 2, "name": "endnotes-second-relationship-xml-calibration", "sha256": "1f4452ca3d4e3b2fb23e9a1fc468092a99b8a0d6d19061665434b3eed4a45dd6", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00003__wfv__endnotes-second-relationship-xml-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:02:25.457 'Word found unreadable content in 00003__wfv__endnotes-second-relationship-xml-calibration.docx. Do  … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:02:25.964 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__endnotes-second-relations...)\""]}
{"run": "s62c", "pass": 1, "name": "s62c-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:01:03+00:00", "staged": "00006__wfv__s62c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62c", "pass": 2, "name": "s62c-control-minimal-end", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:35+00:00", "staged": "00006__wfv__s62c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 1, "name": "s62d-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:55+00:00", "staged": "00003__wfv__s62d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 2, "name": "s62d-control-minimal", "sha256": "ebce42a6e3d60aaddbe0fa31505e6734541e7df5e1d2f1d6644d9e4c9a8e7b65", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:03:11+00:00", "staged": "00003__wfv__s62d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 1, "name": "unrelated-header-dangling-footnote-reference", "sha256": "15f10c7117ea31874f13798b89797abe989ac026b1543878440e117c36534e62", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:55+00:00", "staged": "00004__wfv__unrelated-header-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header-dangling-footnote-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 2, "name": "unrelated-header-dangling-footnote-reference", "sha256": "15f10c7117ea31874f13798b89797abe989ac026b1543878440e117c36534e62", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:03:11+00:00", "staged": "00004__wfv__unrelated-header-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header-dangling-footnote-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 1, "name": "read-header-dangling-endnote-reference", "sha256": "a32503bf0278869aa37b6f4479344b6728765f8bbf15e69194e7f470bbe21893", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:55+00:00", "staged": "00000__wfv__read-header-dangling-endnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-dangling-endnote-reference_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 2, "name": "read-header-dangling-endnote-reference", "sha256": "a32503bf0278869aa37b6f4479344b6728765f8bbf15e69194e7f470bbe21893", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:03:11+00:00", "staged": "00000__wfv__read-header-dangling-endnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-dangling-endnote-reference_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 1, "name": "read-header-matching-endnote-calibration", "sha256": "3d6b5f2dc953f5cabbd8fb5d86c6dc0f94182e80dafc6b1b04cd165b81fe0307", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:55+00:00", "staged": "00001__wfv__read-header-matching-endnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-matching-endnote-calibration_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 2, "name": "read-header-matching-endnote-calibration", "sha256": "3d6b5f2dc953f5cabbd8fb5d86c6dc0f94182e80dafc6b1b04cd165b81fe0307", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:03:11+00:00", "staged": "00001__wfv__read-header-matching-endnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-matching-endnote-calibration_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 1, "name": "s62d-control-minimal-end", "sha256": "b423b28fe6f52d8d5b485aebb50acda6899a4cef0075e137223519da5485e94e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:02:55+00:00", "staged": "00002__wfv__s62d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62d", "pass": 2, "name": "s62d-control-minimal-end", "sha256": "b423b28fe6f52d8d5b485aebb50acda6899a4cef0075e137223519da5485e94e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:03:11+00:00", "staged": "00002__wfv__s62d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 1, "name": "s62e-control-minimal", "sha256": "2de9b5018b2187d1f8aa2f056acf54fa72b4b7247cf0635cd87376fc58f3652c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00003__wfv__s62e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 2, "name": "s62e-control-minimal", "sha256": "2de9b5018b2187d1f8aa2f056acf54fa72b4b7247cf0635cd87376fc58f3652c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00003__wfv__s62e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 1, "name": "two-endnotes-relationships-first-holds-1", "sha256": "d05cca283bacd509c0ce7927db4e403db0ad9f9af0e6ce4e5ad785f5c2f6dda2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00005__wfv__two-endnotes-relationships-first-holds-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:04:43.008 'Word found unreadable content in 00005__wfv__two-endnotes-relationships-first-holds-1.docx. Do you  … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:04:43.548 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__two-endnotes-relationship...)\""]}
{"run": "s62e", "pass": 2, "name": "two-endnotes-relationships-first-holds-1", "sha256": "d05cca283bacd509c0ce7927db4e403db0ad9f9af0e6ce4e5ad785f5c2f6dda2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00005__wfv__two-endnotes-relationships-first-holds-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:06:08.498 \"Word found unreadable content in 00005__wfv__two-endnotes-relationships-first-holds-1.docx. Do you  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s62e", "pass": 1, "name": "two-endnotes-relationships-both-hold-1", "sha256": "472ed10ae373be654d91c1a36deb6feedd9b4cbf2d6f9614732331307100764c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00004__wfv__two-endnotes-relationships-both-hold-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:03:54.491 'Word found unreadable content in 00004__wfv__two-endnotes-relationships-both-hold-1.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:03:55.336 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__two-endnotes-relationship...)\""]}
{"run": "s62e", "pass": 2, "name": "two-endnotes-relationships-both-hold-1", "sha256": "472ed10ae373be654d91c1a36deb6feedd9b4cbf2d6f9614732331307100764c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00004__wfv__two-endnotes-relationships-both-hold-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 16:05:15.059 'Word found unreadable content in 00004__wfv__two-endnotes-relationships-both-hold-1.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 16:05:15.906 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__two-endnotes-relationship...)\""]}
{"run": "s62e", "pass": 1, "name": "two-endnotes-relationships-no-reference", "sha256": "dede60adb185335f3db017983fbae8cb91ce3ab56487e9017205fe74e2e3895e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00006__wfv__two-endnotes-relationships-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF two-endnotes-relationships-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 2, "name": "two-endnotes-relationships-no-reference", "sha256": "dede60adb185335f3db017983fbae8cb91ce3ab56487e9017205fe74e2e3895e", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00006__wfv__two-endnotes-relationships-no-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF two-endnotes-relationships-no-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 1, "name": "read-header-dangling-footnote-reference", "sha256": "75f113e806836f31e63a9f88fad5128fc57da8891521b8f9b0d0d847e28a5696", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00000__wfv__read-header-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-dangling-footnote-reference_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 2, "name": "read-header-dangling-footnote-reference", "sha256": "75f113e806836f31e63a9f88fad5128fc57da8891521b8f9b0d0d847e28a5696", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00000__wfv__read-header-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-dangling-footnote-reference_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 1, "name": "read-header-matching-footnote-calibration", "sha256": "a2227235b01b8a3960421f06fbb2cc4224ecba507de398f9d70ea23b090e8af2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00001__wfv__read-header-matching-footnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-matching-footnote-calibration_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 2, "name": "read-header-matching-footnote-calibration", "sha256": "a2227235b01b8a3960421f06fbb2cc4224ecba507de398f9d70ea23b090e8af2", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00001__wfv__read-header-matching-footnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-header-matching-footnote-calibration_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 1, "name": "s62e-control-minimal-end", "sha256": "2de9b5018b2187d1f8aa2f056acf54fa72b4b7247cf0635cd87376fc58f3652c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:04:43+00:00", "staged": "00002__wfv__s62e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s62e", "pass": 2, "name": "s62e-control-minimal-end", "sha256": "2de9b5018b2187d1f8aa2f056acf54fa72b4b7247cf0635cd87376fc58f3652c", "validatorRevision": "0b09054c3a9836d5bd5498e499a8f91fe6fca67a", "observedAt": "2026-10-26T20:06:08+00:00", "staged": "00002__wfv__s62e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s62e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 62 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s62builder.mts`:

```ts
// Session 62 (2026-10-26): the Word questions the adversarial review of layers 188-191 left open.
// s62a: #799 (comment markers and definitions in an unselected mc:Choice) and #800 (a renamed main document's dangling
//       note references).
// s62b: #801 (note ids spelled 01 or +1 against a note spelled 1, and lexically matching non-canonical calibrations).
// s62c: #802 (comments, endnotes and footnotes parts typed styles with a charset parameter) and the review's suspected
//       non-XML-typed second endnotes part.
// s62d: #800's other half (an unrelated story-named header holding a dangling reference) and the review's source-scope
//       gap (a dangling endnote reference in a read header).
// s62e: added after s62c and s62d ran: separates s62c's two-endnotes-relationship refusals (Word reads one relationship,
//       or refuses the second) and asks s62d's header question for footnotes.
// Every row records the validator revision it was judged at (`validatorRevision`, git rev-parse HEAD of the build
// worktree), per CodeRabbit on #796. Helpers are copied from s58builder.mts and s61builder.mts.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s62a pnpm exec node --import tsx s62builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s62a: withControls("s62a", [
        [
            "comment-reference-only-in-unselected-choice",
            '#799: word/comments.xml holds comment 5; the body\'s only w:commentReference (id 0) sits in mc:Choice Requires="u" (u not understood), the Fallback a text run',
            () => buildDocx(mainWith(withComments(comment("5")), alternate("u", commentRef("0"), "<w:r><w:t>F</w:t></w:r>"))),
        ],
        [
            "comment-definition-only-in-unselected-choice",
            '#799: the body references comment 0; word/comments.xml holds comment 0 only in mc:Choice Requires="u" and comment 5 in the Fallback',
            () => buildDocx(mainWith(withComments(alternate("u", comment("0"), comment("5"))), commentRef("0"))),
        ],
        [
            "comment-definition-in-selected-choice-calibration",
            "#799 calibration: the same, the Choice requiring w14 (understood), so comment 0 is selected",
            () => buildDocx(mainWith(withComments(alternate("w14", comment("0"), comment("5"))), commentRef("0"))),
        ],
        [
            "renamed-main-dangling-endnote",
            "#800: main document stored as word/main.xml (officeDocument target, Override, sidecar renamed); the related word/endnotes.xml holds endnote 5; the body references endnote 1",
            () => buildDocx(renameMain(mainWith(withNotes("endnote", "5"), noteRef("endnote", "1")), "main.xml")),
        ],
        [
            "renamed-main-dangling-footnote",
            "#800: the same for footnotes (word/footnotes.xml holds footnote 5; the body references footnote 1)",
            () => buildDocx(renameMain(mainWith(withNotes("footnote", "5"), noteRef("footnote", "1")), "main.xml")),
        ],
        [
            "renamed-main-matching-endnote-calibration",
            "#800 calibration: main document word/main.xml; the related word/endnotes.xml holds endnote 1; the body references endnote 1",
            () => buildDocx(renameMain(mainWith(withNotes("endnote", "1"), noteRef("endnote", "1")), "main.xml")),
        ],
    ]),
    s62b: withControls("s62b", [
        [
            "footnote-reference-01-note-1",
            '#801: the related word/footnotes.xml holds footnote 1; the body\'s reference spells w:id="01"',
            () => buildDocx(mainWith(withNotes("footnote", "1"), noteRef("footnote", "01"))),
        ],
        [
            "endnote-reference-01-note-1",
            "#801: the same for endnotes",
            () => buildDocx(mainWith(withNotes("endnote", "1"), noteRef("endnote", "01"))),
        ],
        [
            "footnote-reference-plus1-note-1",
            '#801: the related word/footnotes.xml holds footnote 1; the body\'s reference spells w:id="+1"',
            () => buildDocx(mainWith(withNotes("footnote", "1"), noteRef("footnote", "+1"))),
        ],
        [
            "endnote-reference-plus1-note-1",
            "#801: the same for endnotes",
            () => buildDocx(mainWith(withNotes("endnote", "1"), noteRef("endnote", "+1"))),
        ],
        [
            "footnote-reference-01-note-01-calibration",
            '#801 calibration: footnote and reference both spell w:id="01"',
            () => buildDocx(mainWith(withNotes("footnote", "01"), noteRef("footnote", "01"))),
        ],
        [
            "endnote-reference-plus1-note-plus1-calibration",
            '#801 calibration: endnote and reference both spell w:id="+1"',
            () => buildDocx(mainWith(withNotes("endnote", "+1"), noteRef("endnote", "+1"))),
        ],
    ]),
    s62c: withControls("s62c", [
        [
            "comments-typed-styles-charset",
            "#802: a used word/comments.xml (own root, comment 0, referenced) typed styles+xml; charset=utf-8",
            () => buildDocx(mainWith(withComments(comment("0"), `${WML}.styles+xml; charset=utf-8`), commentRef("0"))),
        ],
        [
            "endnotes-typed-styles-charset",
            "#802: a used word/endnotes.xml (own root, endnote 1, referenced) typed styles+xml; charset=utf-8",
            () => buildDocx(mainWith(withNotes("endnote", "1", `${WML}.styles+xml; charset=utf-8`), noteRef("endnote", "1"))),
        ],
        [
            "footnotes-typed-styles-charset",
            "#802: a used word/footnotes.xml (own root, footnote 1, referenced) typed styles+xml; charset=utf-8",
            () => buildDocx(mainWith(withNotes("footnote", "1", `${WML}.styles+xml; charset=utf-8`), noteRef("footnote", "1"))),
        ],
        [
            "comments-typed-comments-charset-calibration",
            "#802 calibration: the same comments part typed comments+xml; charset=utf-8 (its own type with the parameter)",
            () => buildDocx(mainWith(withComments(comment("0"), `${WML}.comments+xml; charset=utf-8`), commentRef("0"))),
        ],
        [
            "endnotes-second-relationship-octet-stream",
            "review suspect: word/endnotes.xml (related) holds endnote 5; a second endnotes relationship names word/notes.bin, Override application/octet-stream, whose XML holds endnote 1; the body references endnote 1",
            () => {
                const parts = withNotes("endnote", "5");
                return buildDocx(
                    mainWith(
                        {
                            ...parts,
                            "word/notes.bin": notesXml("endnote", "1"),
                            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes.bin")),
                            [CT]: overrides(parts[CT]!, ["word/notes.bin", "application/octet-stream"]),
                        },
                        noteRef("endnote", "1"),
                    ),
                );
            },
        ],
        [
            "endnotes-second-relationship-xml-calibration",
            "review suspect calibration: the same with the second part word/notes2.xml typed endnotes+xml",
            () => {
                const parts = withNotes("endnote", "5");
                return buildDocx(
                    mainWith(
                        {
                            ...parts,
                            "word/notes2.xml": notesXml("endnote", "1"),
                            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
                            [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
                        },
                        noteRef("endnote", "1"),
                    ),
                );
            },
        ],
    ]),
    s62d: withControls("s62d", [
        [
            "unrelated-header-dangling-footnote-reference",
            "#800: word/header9.xml, typed header by its Override, named by no relationship, holds a w:footnoteReference to id 7; no footnotes part",
            () =>
                buildDocx({
                    ...P,
                    "word/header9.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${noteRef("footnote", "7")}</w:p></w:hdr>`,
                    [CT]: overrides(P[CT]!, ["word/header9.xml", `${WML}.header+xml`]),
                }),
        ],
        [
            "read-header-dangling-endnote-reference",
            "review source scope: a read header (word/header1.xml, referenced by the section) holds a reference to endnote 1; the related word/endnotes.xml holds endnote 5",
            () => buildDocx(withReadHeader(withNotes("endnote", "5"), noteRef("endnote", "1"))),
        ],
        [
            "read-header-matching-endnote-calibration",
            "calibration: the same with word/endnotes.xml holding endnote 1",
            () => buildDocx(withReadHeader(withNotes("endnote", "1"), noteRef("endnote", "1"))),
        ],
    ]),
    s62e: withControls("s62e", [
        [
            "two-endnotes-relationships-first-holds-1",
            "s62c follow-up: the first endnotes relationship names word/endnotes.xml holding endnote 1, a second names word/notes2.xml (endnotes+xml) holding endnote 5; the body references endnote 1",
            () => twoEndnotes("1", "5", true),
        ],
        [
            "two-endnotes-relationships-both-hold-1",
            "s62c follow-up: the same with both parts holding endnote 1",
            () => twoEndnotes("1", "1", true),
        ],
        [
            "two-endnotes-relationships-no-reference",
            "s62c follow-up: word/endnotes.xml holds endnote 5, word/notes2.xml endnote 1, both related; nothing references an endnote",
            () => twoEndnotes("5", "1", false),
        ],
        [
            "read-header-dangling-footnote-reference",
            "s62d follow-up: a read header holds a reference to footnote 1; the related word/footnotes.xml holds footnote 5",
            () => buildDocx(withReadHeader(withNotes("footnote", "5"), noteRef("footnote", "1"))),
        ],
        [
            "read-header-matching-footnote-calibration",
            "calibration: the same with word/footnotes.xml holding footnote 1",
            () => buildDocx(withReadHeader(withNotes("footnote", "1"), noteRef("footnote", "1"))),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-62 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s62a", "s62b", "s62c", "s62d", "s62e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s62/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-62 parts of docs/plans/evidence/word-probes-2026-10-24.md into s62/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and s62/results.json from compare.py. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s62a", "s62b", "s62c", "s62d", "s62e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s62/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 62: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "The Word questions the adversarial review of layers 188–191 left open: comment markers and definitions in an unselected "
    "`mc:Choice` ([#799](https://github.com/jandira-tech/docx-validate/issues/799)), a renamed main document's note references and "
    "an unrelated story-named header ([#800](https://github.com/jandira-tech/docx-validate/issues/800)), note ids spelled `01` or "
    "`+1` ([#801](https://github.com/jandira-tech/docx-validate/issues/801)), comments and notes parts typed styles with a charset "
    "parameter ([#802](https://github.com/jandira-tech/docx-validate/issues/802)), a second endnotes relationship, and dangling note "
    "references in a read header. Chunk s62e was added after s62c and s62d ran, to separate s62c's second-relationship refusals and "
    "to ask s62d's header question for footnotes. Five chunks, each opening and closing with the minimal control. Each ran twice, "
    "as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and "
    f"`unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen. The builder recorded the validator revision in every row "
    f"(`{rev}`).",
    "",
    "- **#799 (s62a).** A `w:commentReference` that exists only in an unselected Choice opens clean, while word-valid rejects it "
    "(`comment-marker-missing`): a false positive. A body reference whose comment exists only in an unselected Choice of the "
    "comments part gets the recovery offer, while word-valid accepts it: a false negative. The same comments part with the Choice "
    "requiring `w14` opens clean, so Word does process `mc:AlternateContent` among the comments and selects by `Requires`.",
    "- **#800 (s62a, s62d).** With the main document stored as `word/main.xml`, a dangling endnote or footnote reference gets the "
    "recovery offer and the matching calibration opens clean; word-valid accepts both dangling rows: two false negatives. An "
    "unrelated `word/header9.xml` holding a dangling footnote reference opens clean (its PDF is the control's size), while "
    "word-valid rejects it: a false positive.",
    "- **#801 (s62b).** References spelled `01` or `+1` to a note spelled `1` open clean for both kinds, each PDF the size of its "
    "canonical calibration's, so Word compares ids as integers; word-valid rejects all four: four false positives.",
    "- **#802 (s62c).** Used comments, endnotes and footnotes parts typed `styles+xml; charset=utf-8` get the recovery offer, "
    "and word-valid accepts all three: three false negatives. The comments part typed with its own type plus the parameter was "
    "refused in the second run and raised a save prompt in the first, so its outcome is `unknown`.",
    "- **Two endnotes relationships (s62c, s62e).** When the body references an endnote and the main document has two `endnotes` "
    "relationships, Word offers recovery whichever part holds the note, both included, and whether the second part is typed "
    "endnotes or `application/octet-stream`; the same two relationships with no endnote reference open clean. Word-valid accepts "
    "all four refused rows: four false negatives.",
    "- **Note references in a read header (s62d, s62e).** A header the section references, holding a reference to endnote 1 or "
    "footnote 1 that the related notes part does not hold, opens clean, its PDF the size of the matching calibration's; word-valid "
    "rejects both: two false positives.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 62</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 62 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s62builder.mts", ROOT / "s62builder.mts", "ts"), ("compare.py", ROOT / "s62/compare.py", "python"),
                         ("section.py", ROOT / "s62/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s62/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 63: 21:11Z–21:18Z on 2026-10-26, validator columns at 7fd50956

The Word questions the adversarial review of layers 192–196 and session 62 left open: dangling comment references in an ISO Strict package ([#817](https://github.com/jandira-tech/docx-validate/issues/817)), a comments part whose stored root is `mc:AlternateContent` ([#818](https://github.com/jandira-tech/docx-validate/issues/818)), the shapes [#820](https://github.com/jandira-tech/docx-validate/issues/820) named as judged by rule, two review suspicions about where notes are defined, dangling note references in a read footer, two referenced `footnotes` relationships, and session 62's `unknown` charset row. Five chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 27 of 27 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`7fd50956959eafa38d422e9c3c2eca18acfc16fd`).

- **#817 (s63a).** Session 46's Word-saved ISO Strict fixture `tests/fixtures/working/word-clean-strict01.docx` opens clean unchanged. With one more run holding `w:commentReference w:id="99"`, an id its comments part does not define, Word offers recovery, while word-valid accepts it: a false negative, the Strict twin of session 58's s58a refusal.
- **#818 (s63b).** A used comments part whose stored root is `mc:AlternateContent`, its selected `w14` Choice holding the `w:comments` root, gets the recovery offer typed with the styles type and opens clean typed comments. Word-valid rejects the first and accepts the second, matching Word.
- **#820 (s63b, s63c).** A comment range whose start only a Choice requiring `u` holds opens clean, as does the same range with the Choice requiring `w14`; word-valid accepts both, with warnings. A body reference to footnote 1 whose only `footnotes` relationship has `TargetMode="External"` gets the recovery offer, matching word-valid. With the only relationship's target `../../footnotes.xml` and the note stored at `/footnotes.xml`, Word opens the file clean, while word-valid rejects it (`word-footnote-reference-missing`): a false positive. The External row shows Word refuses a body reference whose note it cannot find, so Word most likely resolved the target to `/footnotes.xml`, stopping the `..` segments at the package root; no row here holds the escaping relationship without that part.
- **Notes defined elsewhere (s63c).** The body references footnote 1 while the main document has no `footnotes` relationship and a reached glossary's own relationship names `word/glossary/footnotes.xml` holding footnote 1: Word offers recovery, and word-valid accepts it. The only `footnotes` relationship naming `word/notes.bin`, typed `application/octet-stream` and holding footnote 1: Word offers recovery, and word-valid accepts it. Two false negatives; the matching calibration opens clean.
- **Note references in a read footer (s63d).** A footer the section references, holding a reference to footnote 1 or endnote 1 that the related notes part does not hold, opens clean, its PDF the size of the matching calibration's; word-valid rejects both: two false positives, as session 62 showed for headers.
- **Two footnotes relationships (s63d).** When the body references footnote 1 and the main document has two `footnotes` relationships, Word offers recovery whether the second part holds another id or footnote 1 too; word-valid accepts both: two false negatives, the footnotes counterpart of session 62's endnotes rows.
- **#802 (s63e).** The comments part typed with its own type plus `; charset=utf-8`, `unknown` in session 62, gets the recovery offer in both runs, and word-valid rejects it (`word-part-content-type-inexact`), matching Word.

| Run    | Observed             | Specimen                                             | Shape                                                                                                                                                                                                      | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 7fd50956                     | strict at 7fd50956                                                                                                              |
| ------ | -------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `s63a` | 21:11:17Z, 21:11:41Z | `s63a-control-minimal`                               | control                                                                                                                                                                                                    | `c3a758cde856409c` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63a` | 21:11:17Z, 21:11:41Z | `strict01-unchanged-calibration`                     | #817 calibration: tests/fixtures/working/word-clean-strict01.docx unchanged (ISO Strict, comment 0 fully marked; pinned clean-open in session 46)                                                          | `0a68e7dd97fdadfe` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`                                     |
| `s63a` | 21:11:17Z, 21:11:41Z | `strict01-dangling-comment-reference`                | #817: the same Strict package with one more run holding w:commentReference w:id="99" right after comment 0's reference; the comments part defines only comment 0                                           | `208084668ab60d24` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `comment-thread-count-mismatch`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`, `xsd-summary`, `xsd-error`    |
| `s63a` | 21:11:17Z, 21:11:41Z | `s63a-control-minimal-end`                           | control                                                                                                                                                                                                    | `7b116d8f529c057d` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63b` | 21:12:05Z, 21:12:34Z | `s63b-control-minimal`                               | control                                                                                                                                                                                                    | `7b116d8f529c057d` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63b` | 21:12:05Z, 21:12:34Z | `comments-root-alternate-content-typed-styles`       | #818: a used word/comments.xml whose stored root is mc:AlternateContent; its Choice (Requires="w14") holds the w:comments root with comment 0 (referenced); typed styles+xml                               | `56dad5d823657361` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`          |
| `s63b` | 21:12:05Z, 21:12:34Z | `comments-root-alternate-content-calibration`        | #818 calibration: the same part typed comments+xml (its own type)                                                                                                                                          | `b37f1d3dfcb2826b` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`                                             |
| `s63b` | 21:12:05Z, 21:12:34Z | `comment-range-start-only-in-unselected-choice`      | #820: comment 0 defined (own root); the body's w:commentRangeStart w:id="0" sits only in mc:Choice Requires="u" (empty Fallback); the range end and the reference are outside it                           | `8bb10f3325887bf1` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-orphan-end`, `comment-thread-count-mismatch`, `paraid-missing-element`                                        |
| `s63b` | 21:12:05Z, 21:12:34Z | `comment-range-start-in-selected-choice-calibration` | #820 calibration: the same with the Choice requiring w14 (understood), so the range is whole                                                                                                               | `bfb93d62d9662245` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s63b` | 21:12:05Z, 21:12:34Z | `s63b-control-minimal-end`                           | control                                                                                                                                                                                                    | `7b116d8f529c057d` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63c` | 21:13:52Z, 21:15:02Z | `s63c-control-minimal`                               | control                                                                                                                                                                                                    | `cf60117eee07f708` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63c` | 21:13:52Z, 21:15:02Z | `footnotes-relationship-external`                    | #820: word/footnotes.xml (footnotes+xml) holds footnote 1; the only footnotes relationship names it with TargetMode="External"; the body references footnote 1                                             | `79715e33285c758e` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-footnote-reference-missing`                                       |
| `s63c` | 21:13:52Z, 21:15:02Z | `footnotes-relationship-escaping`                    | #820: footnotes.xml at the package root (footnotes+xml) holds footnote 1; the only footnotes relationship's target is ../../footnotes.xml, escaping the package from word/; the body references footnote 1 | `7276d64613d5e7f9` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-footnote-reference-missing` |
| `s63c` | 21:13:52Z, 21:15:02Z | `footnote-only-in-glossary-notes`                    | review suspicion: the main document has no footnotes relationship; a reached glossary's own sidecar relates word/glossary/footnotes.xml holding footnote 1; the body references footnote 1                 | `aeb2a01bb298e917` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`, `paraid-missing-element`                                                                     |
| `s63c` | 21:13:52Z, 21:15:02Z | `footnotes-only-relationship-octet-stream`           | review suspicion: the only footnotes relationship names word/notes.bin, Override application/octet-stream, whose XML holds footnote 1; the body references footnote 1                                      | `5d06bf06dab3b84d` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-unrecognized`                                                                                  |
| `s63c` | 21:13:52Z, 21:15:02Z | `footnote-matching-calibration`                      | calibration: word/footnotes.xml (footnotes+xml) holds footnote 1, related normally; the body references footnote 1                                                                                         | `dd6ce46f6d61f0c7` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s63c` | 21:13:52Z, 21:15:02Z | `s63c-control-minimal-end`                           | control                                                                                                                                                                                                    | `9337c60a950267f7` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63d` | 21:16:11Z, 21:17:13Z | `s63d-control-minimal`                               | control                                                                                                                                                                                                    | `9337c60a950267f7` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63d` | 21:16:11Z, 21:17:13Z | `read-footer-dangling-footnote-reference`            | #806 footers: a read footer (word/footer1.xml, referenced by the section) holds a reference to footnote 1; the related word/footnotes.xml holds footnote 5                                                 | `882423fcae7fafa0` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing`                                  |
| `s63d` | 21:16:11Z, 21:17:13Z | `read-footer-dangling-endnote-reference`             | #806 footers: the same for endnotes (word/endnotes.xml holds endnote 5)                                                                                                                                    | `27f50905e07d3098` | clean-open     | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-endnote-reference-missing`                                   |
| `s63d` | 21:16:11Z, 21:17:13Z | `read-footer-matching-footnote-calibration`          | calibration: the read footer's reference to footnote 1 with word/footnotes.xml holding footnote 1                                                                                                          | `4276e60f7560a571` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`, `paraid-missing-element`                                                                     |
| `s63d` | 21:16:11Z, 21:17:13Z | `two-footnotes-relationships-first-holds-1`          | #807 twin: the first footnotes relationship names word/footnotes.xml holding footnote 1, a second names word/notes2.xml (footnotes+xml) holding footnote 5; the body references footnote 1                 | `93d04bb4dd7f107e` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s63d` | 21:16:11Z, 21:17:13Z | `two-footnotes-relationships-both-hold-1`            | #807 twin: the same with both parts holding footnote 1                                                                                                                                                     | `85ad98fc72c7d645` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s63d` | 21:16:11Z, 21:17:13Z | `s63d-control-minimal-end`                           | control                                                                                                                                                                                                    | `fde7b9cfe6900a54` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63e` | 21:18:17Z, 21:18:44Z | `s63e-control-minimal`                               | control                                                                                                                                                                                                    | `fde7b9cfe6900a54` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s63e` | 21:18:17Z, 21:18:44Z | `comments-typed-comments-charset-rerun`              | #802 calibration rerun (unknown in s62c): a used word/comments.xml (own root, comment 0, referenced) typed comments+xml; charset=utf-8                                                                     | `399a95d957c27871` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact`  | invalid: `word-part-content-type-inexact`, `comment-thread-count-mismatch`, `paraid-missing-element`                            |
| `s63e` | 21:18:17Z, 21:18:44Z | `s63e-control-minimal-end`                           | control                                                                                                                                                                                                    | `fde7b9cfe6900a54` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |

<details><summary>Raw records, session 63</summary>

```jsonl
{"run": "s63a", "pass": 1, "name": "s63a-control-minimal", "sha256": "c3a758cde856409c9e2cae4ac7ce678cebd6efa9eb53266783a920514feed5f0", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:17+00:00", "staged": "00001__wfv__s63a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63a", "pass": 2, "name": "s63a-control-minimal", "sha256": "c3a758cde856409c9e2cae4ac7ce678cebd6efa9eb53266783a920514feed5f0", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:41+00:00", "staged": "00001__wfv__s63a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63a", "pass": 1, "name": "strict01-unchanged-calibration", "sha256": "0a68e7dd97fdadfe113fd3ece7dff0246134e06bea82cb14bb4495ac5858e722", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:17+00:00", "staged": "00003__wfv__strict01-unchanged-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-unchanged-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s63a", "pass": 2, "name": "strict01-unchanged-calibration", "sha256": "0a68e7dd97fdadfe113fd3ece7dff0246134e06bea82cb14bb4495ac5858e722", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:41+00:00", "staged": "00003__wfv__strict01-unchanged-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF strict01-unchanged-calibration_byword.pdf (1168917 bytes), no dialog named the file"]}
{"run": "s63a", "pass": 1, "name": "strict01-dangling-comment-reference", "sha256": "208084668ab60d24b2a4a0a07b2429833081bc5e7fef217a8fb22c388afddcea", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:17+00:00", "staged": "00002__wfv__strict01-dangling-comment-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:11:16.049 \"Word found unreadable content in 00002__wfv__strict01-dangling-comment-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63a", "pass": 2, "name": "strict01-dangling-comment-reference", "sha256": "208084668ab60d24b2a4a0a07b2429833081bc5e7fef217a8fb22c388afddcea", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:41+00:00", "staged": "00002__wfv__strict01-dangling-comment-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:11:40.931 \"Word found unreadable content in 00002__wfv__strict01-dangling-comment-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63a", "pass": 1, "name": "s63a-control-minimal-end", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:17+00:00", "staged": "00000__wfv__s63a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63a", "pass": 2, "name": "s63a-control-minimal-end", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:11:41+00:00", "staged": "00000__wfv__s63a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 1, "name": "s63b-control-minimal", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00005__wfv__s63b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 2, "name": "s63b-control-minimal", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00005__wfv__s63b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 1, "name": "comments-root-alternate-content-typed-styles", "sha256": "56dad5d82365736189a06455b28abe9c3974dda3efbf6ea5bc876c69e180150e", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00003__wfv__comments-root-alternate-content-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:12:04.293 \"Word found unreadable content in 00003__wfv__comments-root-alternate-content-typed-styles.docx. Do  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63b", "pass": 2, "name": "comments-root-alternate-content-typed-styles", "sha256": "56dad5d82365736189a06455b28abe9c3974dda3efbf6ea5bc876c69e180150e", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00003__wfv__comments-root-alternate-content-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:12:33.043 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00003__wfv__comments-root-alternate-c...)'", "2026-10-26 17:12:33.192 \"Word found unreadable content in 00003__wfv__comments-root-alternate-content-typed-styles.docx. Do  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63b", "pass": 1, "name": "comments-root-alternate-content-calibration", "sha256": "b37f1d3dfcb2826bed48b8aae6dceba2775e2c0f5f0c2386d7d92667fb41ea5e", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00002__wfv__comments-root-alternate-content-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-root-alternate-content-calibration_byword.pdf (34587 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 2, "name": "comments-root-alternate-content-calibration", "sha256": "b37f1d3dfcb2826bed48b8aae6dceba2775e2c0f5f0c2386d7d92667fb41ea5e", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00002__wfv__comments-root-alternate-content-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-root-alternate-content-calibration_byword.pdf (34587 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 1, "name": "comment-range-start-only-in-unselected-choice", "sha256": "8bb10f3325887bf12ca5d13d81a01bd671ad50499fc91b086c62335b738dcd57", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00001__wfv__comment-range-start-only-in-unselected-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-range-start-only-in-unselected-choice_byword.pdf (38174 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 2, "name": "comment-range-start-only-in-unselected-choice", "sha256": "8bb10f3325887bf12ca5d13d81a01bd671ad50499fc91b086c62335b738dcd57", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00001__wfv__comment-range-start-only-in-unselected-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-range-start-only-in-unselected-choice_byword.pdf (38174 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 1, "name": "comment-range-start-in-selected-choice-calibration", "sha256": "bfb93d62d96622456fb6f8ef021137a63603240edb02e1d32d2aea0e03a4d9ab", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00000__wfv__comment-range-start-in-selected-choice-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-range-start-in-selected-choice-calibration_byword.pdf (38232 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 2, "name": "comment-range-start-in-selected-choice-calibration", "sha256": "bfb93d62d96622456fb6f8ef021137a63603240edb02e1d32d2aea0e03a4d9ab", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00000__wfv__comment-range-start-in-selected-choice-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comment-range-start-in-selected-choice-calibration_byword.pdf (38232 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 1, "name": "s63b-control-minimal-end", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:05+00:00", "staged": "00004__wfv__s63b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63b", "pass": 2, "name": "s63b-control-minimal-end", "sha256": "7b116d8f529c057dbf5fe4aaca41e3db762e389cffc61f6a07b835563531c841", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:12:34+00:00", "staged": "00004__wfv__s63b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 1, "name": "s63c-control-minimal", "sha256": "cf60117eee07f708cd9a64a9ead5f12b71468a20e731c31b704c040d5a19f660", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00006__wfv__s63c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 2, "name": "s63c-control-minimal", "sha256": "cf60117eee07f708cd9a64a9ead5f12b71468a20e731c31b704c040d5a19f660", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00006__wfv__s63c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 1, "name": "footnotes-relationship-external", "sha256": "79715e33285c758e267e27fea07123ffaa957de23f2a5c986f59ad780fe956a0", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00004__wfv__footnotes-relationship-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:13:51.292 \"Word found unreadable content in 00004__wfv__footnotes-relationship-external.docx. Do you want to r … ? If you trust the source of this document, click Yes.\"", "2026-10-26 17:13:51.292 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__footnotes-relationship-ex...)\""]}
{"run": "s63c", "pass": 2, "name": "footnotes-relationship-external", "sha256": "79715e33285c758e267e27fea07123ffaa957de23f2a5c986f59ad780fe956a0", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00004__wfv__footnotes-relationship-external.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:15:01.542 \"Word found unreadable content in 00004__wfv__footnotes-relationship-external.docx. Do you want to r … ? If you trust the source of this document, click Yes.\"", "2026-10-26 17:15:01.543 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__footnotes-relationship-ex...)\""]}
{"run": "s63c", "pass": 1, "name": "footnotes-relationship-escaping", "sha256": "7276d64613d5e7f98d04858888b369db538e27cc3de426b27e86ed4dd05457b3", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00003__wfv__footnotes-relationship-escaping.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-relationship-escaping_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 2, "name": "footnotes-relationship-escaping", "sha256": "7276d64613d5e7f98d04858888b369db538e27cc3de426b27e86ed4dd05457b3", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00003__wfv__footnotes-relationship-escaping.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-relationship-escaping_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 1, "name": "footnote-only-in-glossary-notes", "sha256": "aeb2a01bb298e91792ea71e9fd4bdcb0d3ae78bd3e99cbc52fc2d5fc3fc75344", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00001__wfv__footnote-only-in-glossary-notes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:13:11.821 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00001__wfv__footnote-only-in-glossary...)'", "2026-10-26 17:13:11.976 \"Word found unreadable content in 00001__wfv__footnote-only-in-glossary-notes.docx. Do you want to r … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63c", "pass": 2, "name": "footnote-only-in-glossary-notes", "sha256": "aeb2a01bb298e91792ea71e9fd4bdcb0d3ae78bd3e99cbc52fc2d5fc3fc75344", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00001__wfv__footnote-only-in-glossary-notes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:14:20.765 'Word found unreadable content in 00001__wfv__footnote-only-in-glossary-notes.docx. Do you want to r … ? If you trust the source of this document, click Yes.'"]}
{"run": "s63c", "pass": 1, "name": "footnotes-only-relationship-octet-stream", "sha256": "5d06bf06dab3b84dda54bd82befe3ad13ed33be658381f665c9cda3863386dc6", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00002__wfv__footnotes-only-relationship-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:13:45.545 'Word found unreadable content in 00002__wfv__footnotes-only-relationship-octet-stream.docx. Do you  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s63c", "pass": 2, "name": "footnotes-only-relationship-octet-stream", "sha256": "5d06bf06dab3b84dda54bd82befe3ad13ed33be658381f665c9cda3863386dc6", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00002__wfv__footnotes-only-relationship-octet-stream.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:14:54.470 'Word found unreadable content in 00002__wfv__footnotes-only-relationship-octet-stream.docx. Do you  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s63c", "pass": 1, "name": "footnote-matching-calibration", "sha256": "dd6ce46f6d61f0c73c2898aeba7cb0c1c850f10894d88739ccadd2a9d093b730", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00000__wfv__footnote-matching-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-matching-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 2, "name": "footnote-matching-calibration", "sha256": "dd6ce46f6d61f0c73c2898aeba7cb0c1c850f10894d88739ccadd2a9d093b730", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00000__wfv__footnote-matching-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnote-matching-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 1, "name": "s63c-control-minimal-end", "sha256": "9337c60a950267f77f1cd145f2394ab40db0319a6a7c29f081ab1fa8d52a8243", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:13:52+00:00", "staged": "00005__wfv__s63c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63c", "pass": 2, "name": "s63c-control-minimal-end", "sha256": "9337c60a950267f77f1cd145f2394ab40db0319a6a7c29f081ab1fa8d52a8243", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:15:02+00:00", "staged": "00005__wfv__s63c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 1, "name": "s63d-control-minimal", "sha256": "9337c60a950267f77f1cd145f2394ab40db0319a6a7c29f081ab1fa8d52a8243", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00004__wfv__s63d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 2, "name": "s63d-control-minimal", "sha256": "9337c60a950267f77f1cd145f2394ab40db0319a6a7c29f081ab1fa8d52a8243", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00004__wfv__s63d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 1, "name": "read-footer-dangling-footnote-reference", "sha256": "882423fcae7fafa025b363a04331a314c82e10e07cf0c5bc2126972b1cee5615", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00001__wfv__read-footer-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-dangling-footnote-reference_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 2, "name": "read-footer-dangling-footnote-reference", "sha256": "882423fcae7fafa025b363a04331a314c82e10e07cf0c5bc2126972b1cee5615", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00001__wfv__read-footer-dangling-footnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-dangling-footnote-reference_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 1, "name": "read-footer-dangling-endnote-reference", "sha256": "27f50905e07d3098f5f2f0fb296892abe5f209db337ba47451d3b2c8a61b0007", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00000__wfv__read-footer-dangling-endnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-dangling-endnote-reference_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 2, "name": "read-footer-dangling-endnote-reference", "sha256": "27f50905e07d3098f5f2f0fb296892abe5f209db337ba47451d3b2c8a61b0007", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00000__wfv__read-footer-dangling-endnote-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-dangling-endnote-reference_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 1, "name": "read-footer-matching-footnote-calibration", "sha256": "4276e60f7560a571a98ad8243b34413a2a8d468af8db4427b9da65a8e1483e31", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00002__wfv__read-footer-matching-footnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-matching-footnote-calibration_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 2, "name": "read-footer-matching-footnote-calibration", "sha256": "4276e60f7560a571a98ad8243b34413a2a8d468af8db4427b9da65a8e1483e31", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00002__wfv__read-footer-matching-footnote-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF read-footer-matching-footnote-calibration_byword.pdf (14774 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 1, "name": "two-footnotes-relationships-first-holds-1", "sha256": "93d04bb4dd7f107e27214d28a43abae7537e567d1e04be0ec4b6c067bc829087", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00006__wfv__two-footnotes-relationships-first-holds-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:16:10.857 Microsoft Word, Word found unreadable content in 00006__wfv__two-footnotes-relationships-first-holds … t? If you trust the source of this document, click Yes."]}
{"run": "s63d", "pass": 2, "name": "two-footnotes-relationships-first-holds-1", "sha256": "93d04bb4dd7f107e27214d28a43abae7537e567d1e04be0ec4b6c067bc829087", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00006__wfv__two-footnotes-relationships-first-holds-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:17:13.719 'Word found unreadable content in 00006__wfv__two-footnotes-relationships-first-holds-1.docx. Do you … ? If you trust the source of this document, click Yes.'"]}
{"run": "s63d", "pass": 1, "name": "two-footnotes-relationships-both-hold-1", "sha256": "85ad98fc72c7d6459f7056ed898e1151a1b0532ca58c9da4702bdf66df4a91f8", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00005__wfv__two-footnotes-relationships-both-hold-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:15:26.820 \"Word found unreadable content in 00005__wfv__two-footnotes-relationships-both-hold-1.docx. Do you w … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63d", "pass": 2, "name": "two-footnotes-relationships-both-hold-1", "sha256": "85ad98fc72c7d6459f7056ed898e1151a1b0532ca58c9da4702bdf66df4a91f8", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00005__wfv__two-footnotes-relationships-both-hold-1.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:16:40.042 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00005__wfv__two-footnotes-relationshi...)'", "2026-10-26 17:16:40.177 \"Word found unreadable content in 00005__wfv__two-footnotes-relationships-both-hold-1.docx. Do you w … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63d", "pass": 1, "name": "s63d-control-minimal-end", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:16:11+00:00", "staged": "00003__wfv__s63d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63d", "pass": 2, "name": "s63d-control-minimal-end", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:17:13+00:00", "staged": "00003__wfv__s63d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63e", "pass": 1, "name": "s63e-control-minimal", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:17+00:00", "staged": "00002__wfv__s63e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63e", "pass": 2, "name": "s63e-control-minimal", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:44+00:00", "staged": "00002__wfv__s63e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63e", "pass": 1, "name": "comments-typed-comments-charset-rerun", "sha256": "399a95d957c2787195b7623c2e9f0503567b2846a427600ba3e2188d64b29e11", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:17+00:00", "staged": "00000__wfv__comments-typed-comments-charset-rerun.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:18:15.546 Microsoft Word, Word found unreadable content in 00000__wfv__comments-typed-comments-charset-rerun.d … t? If you trust the source of this document, click Yes.", "2026-10-26 17:18:16.232 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-typed-comments-c...)\""]}
{"run": "s63e", "pass": 2, "name": "comments-typed-comments-charset-rerun", "sha256": "399a95d957c2787195b7623c2e9f0503567b2846a427600ba3e2188d64b29e11", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:44+00:00", "staged": "00000__wfv__comments-typed-comments-charset-rerun.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:18:43.167 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00000__wfv__comments-typed-comments-c...)'", "2026-10-26 17:18:43.263 \"Word found unreadable content in 00000__wfv__comments-typed-comments-charset-rerun.docx. Do you wan … ? If you trust the source of this document, click Yes.\""]}
{"run": "s63e", "pass": 1, "name": "s63e-control-minimal-end", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:17+00:00", "staged": "00001__wfv__s63e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s63e", "pass": 2, "name": "s63e-control-minimal-end", "sha256": "fde7b9cfe6900a542af246297217c80b90c5c84074fd5da4f072fdc53b307fc5", "validatorRevision": "7fd50956959eafa38d422e9c3c2eca18acfc16fd", "observedAt": "2026-10-26T21:18:44+00:00", "staged": "00001__wfv__s63e-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s63e-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 63 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s63builder.mts`:

```ts
// Session 63 (2026-10-26): the Word questions the adversarial review of layers 192-196 and session 62 left open.
// s63a: #817 (a dangling comment reference in an ISO Strict package: Word's own word-clean-strict01 fixture, pinned
//       clean-open, with one extra w:commentReference to an id its comments part does not define).
// s63b: #818 (a comments part whose STORED root is mc:AlternateContent, typed styles) and #820 (a comment range whose
//       start only an unselected mc:Choice holds).
// s63c: #820 (a notes relationship with TargetMode="External", or a target escaping the package) and two review
//       suspicions (a main-body reference satisfied only by a reached glossary's notes part; an octet-stream notes part).
// s63d: #806's footers (a dangling note reference in a read footer) and #807's footnotes twin (two referenced footnotes
//       relationships).
// s63e: #802's calibration row, `unknown` in s62c, alone.
// Every row records the validator revision it was judged at (`validatorRevision`). Helpers are copied from s62builder.mts.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s63a pnpm exec node --import tsx s63builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, extra = "") =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${extra}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

/** The minimal parts with `word/footer1.xml` read through the section's default footer reference, holding `run`. */
const withReadFooter = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r>${run}</w:p></w:ftr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
            [CT]: overrides(parts[CT]!, ["word/footer1.xml", `${WML}.footer+xml`]),
        },
        "",
        `<w:footerReference w:type="default" r:id="rIdF"/>`,
    );

/** Two footnotes relationships in document order: word/footnotes.xml holding `first`, then word/notes2.xml (footnotes+xml) holding `second`; the body references footnote 1. */
const twoFootnotes = (first: string, second: string) => {
    const parts = withNotes("footnote", first);
    return buildDocx(
        mainWith(
            {
                ...parts,
                "word/notes2.xml": notesXml("footnote", second),
                [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "footnotes", "notes2.xml")),
                [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.footnotes+xml`]),
            },
            noteRef("footnote", "1"),
        ),
    );
};

/** Session 46's Word-saved ISO Strict fixture (pinned clean-open), with `edit` applied to its main document. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (main: string) => string = (main) => main) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    parts[MAIN] = edit(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};

/** A used `word/comments.xml` whose stored root is mc:AlternateContent; its w14 Choice holds the w:comments root with comment 0. */
const rootAlternateComments = (type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml":
                    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">` +
                    `<w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** Comment 0 (own root) with its range start inside an mc:Choice requiring `requires` (empty Fallback), the end and the reference outside. */
const splitRange = (requires: string) =>
    buildDocx(
        mainWith(
            withComments(comment("0")),
            alternate(requires, `<w:commentRangeStart w:id="0"/>`, "") +
                `<w:r><w:t>ranged</w:t></w:r><w:commentRangeEnd w:id="0"/>` +
                commentRef("0"),
        ),
    );

/** The minimal package with a reached glossary whose own sidecar relates word/glossary/footnotes.xml holding footnote `held`. */
const glossaryWithFootnotes = (held: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${TEXT_P}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "footnotes", "footnotes.xml")}</Relationships>`,
    "word/glossary/footnotes.xml": notesXml("footnote", held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(
        P[CT]!,
        ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
        ["word/glossary/footnotes.xml", `${WML}.footnotes+xml`],
    ),
});
/** Footnote 1 stored at `stored`, typed `type`, named only by a footnotes relationship with `target` and `extra`; the body references footnote 1. */
const footnotesAt = (stored: string, type: string, target: string, extra = "") =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml("footnote", "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target, extra)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef("footnote", "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const FOOTNOTES = `${WML}.footnotes+xml`;

const chunks: Record<string, Row[]> = {
    s63a: withControls("s63a", [
        [
            "strict01-unchanged-calibration",
            "#817 calibration: tests/fixtures/working/word-clean-strict01.docx unchanged (ISO Strict, comment 0 fully marked; pinned clean-open in session 46)",
            () => strict01(),
        ],
        [
            "strict01-dangling-comment-reference",
            '#817: the same Strict package with one more run holding w:commentReference w:id="99" right after comment 0\'s reference; the comments part defines only comment 0',
            () =>
                strict01((main) =>
                    replaceOnce(
                        main,
                        `<w:commentReference w:id="0"/></w:r>`,
                        `<w:commentReference w:id="0"/></w:r><w:r><w:commentReference w:id="99"/></w:r>`,
                    ),
                ),
        ],
    ]),
    s63b: withControls("s63b", [
        [
            "comments-root-alternate-content-typed-styles",
            '#818: a used word/comments.xml whose stored root is mc:AlternateContent; its Choice (Requires="w14") holds the w:comments root with comment 0 (referenced); typed styles+xml',
            () => rootAlternateComments(`${WML}.styles+xml`),
        ],
        [
            "comments-root-alternate-content-calibration",
            "#818 calibration: the same part typed comments+xml (its own type)",
            () => rootAlternateComments(`${WML}.comments+xml`),
        ],
        [
            "comment-range-start-only-in-unselected-choice",
            '#820: comment 0 defined (own root); the body\'s w:commentRangeStart w:id="0" sits only in mc:Choice Requires="u" (empty Fallback); the range end and the reference are outside it',
            () => splitRange("u"),
        ],
        [
            "comment-range-start-in-selected-choice-calibration",
            "#820 calibration: the same with the Choice requiring w14 (understood), so the range is whole",
            () => splitRange("w14"),
        ],
    ]),
    s63c: withControls("s63c", [
        [
            "footnotes-relationship-external",
            '#820: word/footnotes.xml (footnotes+xml) holds footnote 1; the only footnotes relationship names it with TargetMode="External"; the body references footnote 1',
            () => footnotesAt("word/footnotes.xml", FOOTNOTES, "footnotes.xml", ` TargetMode="External"`),
        ],
        [
            "footnotes-relationship-escaping",
            "#820: footnotes.xml at the package root (footnotes+xml) holds footnote 1; the only footnotes relationship's target is ../../footnotes.xml, escaping the package from word/; the body references footnote 1",
            () => footnotesAt("footnotes.xml", FOOTNOTES, "../../footnotes.xml"),
        ],
        [
            "footnote-only-in-glossary-notes",
            "review suspicion: the main document has no footnotes relationship; a reached glossary's own sidecar relates word/glossary/footnotes.xml holding footnote 1; the body references footnote 1",
            () => buildDocx(mainWith(glossaryWithFootnotes("1"), noteRef("footnote", "1"))),
        ],
        [
            "footnotes-only-relationship-octet-stream",
            "review suspicion: the only footnotes relationship names word/notes.bin, Override application/octet-stream, whose XML holds footnote 1; the body references footnote 1",
            () => footnotesAt("word/notes.bin", "application/octet-stream", "notes.bin"),
        ],
        [
            "footnote-matching-calibration",
            "calibration: word/footnotes.xml (footnotes+xml) holds footnote 1, related normally; the body references footnote 1",
            () => footnotesAt("word/footnotes.xml", FOOTNOTES, "footnotes.xml"),
        ],
    ]),
    s63d: withControls("s63d", [
        [
            "read-footer-dangling-footnote-reference",
            "#806 footers: a read footer (word/footer1.xml, referenced by the section) holds a reference to footnote 1; the related word/footnotes.xml holds footnote 5",
            () => buildDocx(withReadFooter(withNotes("footnote", "5"), noteRef("footnote", "1"))),
        ],
        [
            "read-footer-dangling-endnote-reference",
            "#806 footers: the same for endnotes (word/endnotes.xml holds endnote 5)",
            () => buildDocx(withReadFooter(withNotes("endnote", "5"), noteRef("endnote", "1"))),
        ],
        [
            "read-footer-matching-footnote-calibration",
            "calibration: the read footer's reference to footnote 1 with word/footnotes.xml holding footnote 1",
            () => buildDocx(withReadFooter(withNotes("footnote", "1"), noteRef("footnote", "1"))),
        ],
        [
            "two-footnotes-relationships-first-holds-1",
            "#807 twin: the first footnotes relationship names word/footnotes.xml holding footnote 1, a second names word/notes2.xml (footnotes+xml) holding footnote 5; the body references footnote 1",
            () => twoFootnotes("1", "5"),
        ],
        ["two-footnotes-relationships-both-hold-1", "#807 twin: the same with both parts holding footnote 1", () => twoFootnotes("1", "1")],
    ]),
    s63e: withControls("s63e", [
        [
            "comments-typed-comments-charset-rerun",
            "#802 calibration rerun (unknown in s62c): a used word/comments.xml (own root, comment 0, referenced) typed comments+xml; charset=utf-8",
            () => buildDocx(mainWith(withComments(comment("0"), `${WML}.comments+xml; charset=utf-8`), commentRef("0"))),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-63 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s63a", "s63b", "s63c", "s63d", "s63e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s63/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-63 parts of docs/plans/evidence/word-probes-2026-10-24.md into s63/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and s63/results.json from compare.py. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s63a", "s63b", "s63c", "s63d", "s63e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s63/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 63: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "The Word questions the adversarial review of layers 192–196 and session 62 left open: dangling comment references in an ISO "
    "Strict package ([#817](https://github.com/jandira-tech/docx-validate/issues/817)), a comments part whose stored root is "
    "`mc:AlternateContent` ([#818](https://github.com/jandira-tech/docx-validate/issues/818)), the shapes "
    "[#820](https://github.com/jandira-tech/docx-validate/issues/820) named as judged by rule, two review suspicions about where "
    "notes are defined, dangling note references in a read footer, two referenced `footnotes` relationships, and session 62's "
    "`unknown` charset row. Five chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver "
    "runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    f"builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "- **#817 (s63a).** Session 46's Word-saved ISO Strict fixture `tests/fixtures/working/word-clean-strict01.docx` opens clean "
    "unchanged. With one more run holding `w:commentReference w:id=\"99\"`, an id its comments part does not define, Word offers "
    "recovery, while word-valid accepts it: a false negative, the Strict twin of session 58's s58a refusal.",
    "- **#818 (s63b).** A used comments part whose stored root is `mc:AlternateContent`, its selected `w14` Choice holding the "
    "`w:comments` root, gets the recovery offer typed with the styles type and opens clean typed comments. Word-valid rejects the "
    "first and accepts the second, matching Word.",
    "- **#820 (s63b, s63c).** A comment range whose start only a Choice requiring `u` holds opens clean, as does the same range "
    "with the Choice requiring `w14`; word-valid accepts both, with warnings. A body reference to footnote 1 whose only `footnotes` "
    "relationship has `TargetMode=\"External\"` gets the recovery offer, matching word-valid. With the only relationship's target "
    "`../../footnotes.xml` and the note stored at `/footnotes.xml`, Word opens the file clean, while word-valid rejects it "
    "(`word-footnote-reference-missing`): a false positive. The External row shows Word refuses a body reference whose note it "
    "cannot find, so Word most likely resolved the target to `/footnotes.xml`, stopping the `..` segments at the package root; "
    "no row here holds the escaping relationship without that part.",
    "- **Notes defined elsewhere (s63c).** The body references footnote 1 while the main document has no `footnotes` relationship "
    "and a reached glossary's own relationship names `word/glossary/footnotes.xml` holding footnote 1: Word offers recovery, "
    "and word-valid accepts it. The only `footnotes` relationship naming `word/notes.bin`, typed `application/octet-stream` and "
    "holding footnote 1: Word offers recovery, and word-valid accepts it. Two false negatives; the matching calibration opens clean.",
    "- **Note references in a read footer (s63d).** A footer the section references, holding a reference to footnote 1 or "
    "endnote 1 that the related notes part does not hold, opens clean, its PDF the size of the matching calibration's; word-valid "
    "rejects both: two false positives, as session 62 showed for headers.",
    "- **Two footnotes relationships (s63d).** When the body references footnote 1 and the main document has two `footnotes` "
    "relationships, Word offers recovery whether the second part holds another id or footnote 1 too; word-valid accepts both: "
    "two false negatives, the footnotes counterpart of session 62's endnotes rows.",
    "- **#802 (s63e).** The comments part typed with its own type plus `; charset=utf-8`, `unknown` in session 62, gets the "
    "recovery offer in both runs, and word-valid rejects it (`word-part-content-type-inexact`), matching Word.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 63</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 63 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s63builder.mts", ROOT / "s63builder.mts", "ts"), ("compare.py", ROOT / "s63/compare.py", "python"),
                         ("section.py", ROOT / "s63/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s63/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 64: 21:32Z–21:38Z on 2026-10-26, validator columns at b89c9534

Two confirmations session 63's fixes waited on: how Word resolves a notes relationship target that escapes the package ([#830](https://github.com/jandira-tech/docx-validate/issues/830)), and whether a notes part typed `application/octet-stream` defines nothing whatever its name ([#829](https://github.com/jandira-tech/docx-validate/issues/829)). Two chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 12 of 12 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`b89c953441eff860c3c46a790e4a12b472468a01`).

- **Escaping targets (s64a).** With the only `footnotes` relationship targeting `../../footnotes.xml` from `word/`, Word opens the file clean when footnote 1 sits in `/footnotes.xml` (session 63's row, repeated) and offers recovery when it sits only in `word/footnotes.xml`. `../../../footnotes.xml` with the note in `/footnotes.xml`, and the endnotes twin of `../../endnotes.xml`, open clean too, as does the in-package `../footnotes.xml` calibration. Word resolves the target as RFC 3986 does, stopping `..` segments at the package root. Word-valid rejects the three clean escaping rows: three false positives.
- **Octet-stream notes parts (s64b).** With the only `footnotes` relationship naming a part typed `application/octet-stream` that holds footnote 1, Word offers recovery whether the part is `word/notes.xml`, `word/footnotes.xml` or `word/notes.bin` (session 63's row, repeated). The type, not the name, makes the part define nothing. Word-valid accepts all three: three false negatives.

| Run    | Observed             | Specimen                                            | Shape                                                                                                                         | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at b89c9534                     | strict at b89c9534                                                                                                              |
| ------ | -------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `s64a` | 21:32:06Z, 21:32:36Z | `s64a-control-minimal`                              | control                                                                                                                       | `47c631aec06a1108` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s64a` | 21:32:06Z, 21:32:36Z | `footnotes-escaping-two-levels-note-at-root-repeat` | repeat of s63c: the only footnotes relationship targets ../../footnotes.xml from word/; footnote 1 sits in /footnotes.xml     | `70737a72dbf294e5` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-footnote-reference-missing` |
| `s64a` | 21:32:06Z, 21:32:36Z | `footnotes-escaping-two-levels-note-in-word-folder` | the only footnotes relationship targets ../../footnotes.xml; footnote 1 sits only in word/footnotes.xml (no /footnotes.xml)   | `cf81e016549c8464` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-footnote-reference-missing` |
| `s64a` | 21:32:06Z, 21:32:36Z | `footnotes-escaping-three-levels-note-at-root`      | the only footnotes relationship targets ../../../footnotes.xml; footnote 1 sits in /footnotes.xml                             | `1f5154fb3f9bc690` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-footnote-reference-missing` |
| `s64a` | 21:32:06Z, 21:32:36Z | `endnotes-escaping-two-levels-note-at-root`         | endnotes twin of s63c: the only endnotes relationship targets ../../endnotes.xml; endnote 1 sits in /endnotes.xml             | `31b1b6eb37f5397f` | clean-open     | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-endnote-reference-missing`  |
| `s64a` | 21:32:06Z, 21:32:36Z | `footnotes-one-level-note-at-root-calibration`      | calibration: the only footnotes relationship targets ../footnotes.xml (inside the package); footnote 1 sits in /footnotes.xml | `3475e289ba44b4c8` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s64a` | 21:32:06Z, 21:32:36Z | `s64a-control-minimal-end`                          | control                                                                                                                       | `5f5c123817450144` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s64b` | 21:34:35Z, 21:38:54Z | `s64b-control-minimal`                              | control                                                                                                                       | `5f5c123817450144` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s64b` | 21:34:35Z, 21:38:54Z | `footnotes-octet-stream-xml-name`                   | the only footnotes relationship names word/notes.xml, Override application/octet-stream, holding footnote 1                   | `7698b0b7bec17f71` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-unrecognized`                                                                                  |
| `s64b` | 21:34:35Z, 21:38:54Z | `footnotes-octet-stream-standard-name`              | the only footnotes relationship names word/footnotes.xml, Override application/octet-stream, holding footnote 1               | `04c21d147ff2e848` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-unrecognized`, `paraid-missing-element`                                                        |
| `s64b` | 21:34:35Z, 21:38:54Z | `footnotes-octet-stream-bin-repeat`                 | repeat of s63c: the only footnotes relationship names word/notes.bin, Override application/octet-stream, holding footnote 1   | `c229e9f48a63c925` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `word-part-content-type-unrecognized`                                                                                  |
| `s64b` | 21:34:35Z, 21:38:54Z | `s64b-control-minimal-end`                          | control                                                                                                                       | `5f5c123817450144` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |

<details><summary>Raw records, session 64</summary>

```jsonl
{"run": "s64a", "pass": 1, "name": "s64a-control-minimal", "sha256": "47c631aec06a11086c6e84f292920be22e5852c840b6b5094feabfb3b7e76767", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00006__wfv__s64a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "s64a-control-minimal", "sha256": "47c631aec06a11086c6e84f292920be22e5852c840b6b5094feabfb3b7e76767", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00006__wfv__s64a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 1, "name": "footnotes-escaping-two-levels-note-at-root-repeat", "sha256": "70737a72dbf294e535f6ae26086b817dea6c9f27b61b5e4e1d239a8fbcb8347d", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00002__wfv__footnotes-escaping-two-levels-note-at-root-repeat.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-two-levels-note-at-root-repeat_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "footnotes-escaping-two-levels-note-at-root-repeat", "sha256": "70737a72dbf294e535f6ae26086b817dea6c9f27b61b5e4e1d239a8fbcb8347d", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00002__wfv__footnotes-escaping-two-levels-note-at-root-repeat.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-two-levels-note-at-root-repeat_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 1, "name": "footnotes-escaping-two-levels-note-in-word-folder", "sha256": "cf81e016549c846408b621c1feb4f30a0c9ca0e74b3f8ce5b05c9fd67d2bff8e", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00003__wfv__footnotes-escaping-two-levels-note-in-word-folder.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:31:34.901 \"Word found unreadable content in 00003__wfv__footnotes-escaping-two-levels-note-in-word-folde.... D … ? If you trust the source of this document, click Yes.\"", "2026-10-26 17:32:06.327 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__footnotes-escaping-two-le...)\""]}
{"run": "s64a", "pass": 2, "name": "footnotes-escaping-two-levels-note-in-word-folder", "sha256": "cf81e016549c846408b621c1feb4f30a0c9ca0e74b3f8ce5b05c9fd67d2bff8e", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00003__wfv__footnotes-escaping-two-levels-note-in-word-folder.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:32:21.873 'Word found unreadable content in 00003__wfv__footnotes-escaping-two-levels-note-in-word-folde.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 17:32:22.731 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__footnotes-escaping-two-le...)\""]}
{"run": "s64a", "pass": 1, "name": "footnotes-escaping-three-levels-note-at-root", "sha256": "1f5154fb3f9bc690621363c75f9aad94abe4a8a4d559b17226f36d6bc770918d", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00001__wfv__footnotes-escaping-three-levels-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-three-levels-note-at-root_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "footnotes-escaping-three-levels-note-at-root", "sha256": "1f5154fb3f9bc690621363c75f9aad94abe4a8a4d559b17226f36d6bc770918d", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00001__wfv__footnotes-escaping-three-levels-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-three-levels-note-at-root_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 1, "name": "endnotes-escaping-two-levels-note-at-root", "sha256": "31b1b6eb37f5397fa86deddec46ac8158b4aed0cd71c92c407fd9ad8720a7c25", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00000__wfv__endnotes-escaping-two-levels-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-escaping-two-levels-note-at-root_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "endnotes-escaping-two-levels-note-at-root", "sha256": "31b1b6eb37f5397fa86deddec46ac8158b4aed0cd71c92c407fd9ad8720a7c25", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00000__wfv__endnotes-escaping-two-levels-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-escaping-two-levels-note-at-root_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 1, "name": "footnotes-one-level-note-at-root-calibration", "sha256": "3475e289ba44b4c832621ff8002c9b10a1747461b9ce4c070e444cc12f8125f4", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00004__wfv__footnotes-one-level-note-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-one-level-note-at-root-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "footnotes-one-level-note-at-root-calibration", "sha256": "3475e289ba44b4c832621ff8002c9b10a1747461b9ce4c070e444cc12f8125f4", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00004__wfv__footnotes-one-level-note-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-one-level-note-at-root-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 1, "name": "s64a-control-minimal-end", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:06+00:00", "staged": "00005__wfv__s64a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64a", "pass": 2, "name": "s64a-control-minimal-end", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:32:36+00:00", "staged": "00005__wfv__s64a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64b", "pass": 1, "name": "s64b-control-minimal", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:34:35+00:00", "staged": "00004__wfv__s64b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64b", "pass": 2, "name": "s64b-control-minimal", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:38:54+00:00", "staged": "00004__wfv__s64b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64b", "pass": 1, "name": "footnotes-octet-stream-xml-name", "sha256": "7698b0b7bec17f712aba035bffda8d7b2b85835455525b49479a11ea6c8c9edc", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:34:35+00:00", "staged": "00002__wfv__footnotes-octet-stream-xml-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:34:32.430 Microsoft Word, Word found unreadable content in 00002__wfv__footnotes-octet-stream-xml-name.docx. D … t? If you trust the source of this document, click Yes.", "2026-10-26 17:34:33.128 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__footnotes-octet-stream-xm...)\""]}
{"run": "s64b", "pass": 2, "name": "footnotes-octet-stream-xml-name", "sha256": "7698b0b7bec17f712aba035bffda8d7b2b85835455525b49479a11ea6c8c9edc", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:38:54+00:00", "staged": "00002__wfv__footnotes-octet-stream-xml-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:38:51.701 'Word found unreadable content in 00002__wfv__footnotes-octet-stream-xml-name.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-26 17:38:52.837 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__footnotes-octet-stream-xm...)\""]}
{"run": "s64b", "pass": 1, "name": "footnotes-octet-stream-standard-name", "sha256": "04c21d147ff2e84831d246ce7ce84b0b2efa2dd6ef27d78d67344db1db4915cf", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:34:35+00:00", "staged": "00001__wfv__footnotes-octet-stream-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:33:43.515 Microsoft Word, Word found unreadable content in 00001__wfv__footnotes-octet-stream-standard-name.do … t? If you trust the source of this document, click Yes."]}
{"run": "s64b", "pass": 2, "name": "footnotes-octet-stream-standard-name", "sha256": "04c21d147ff2e84831d246ce7ce84b0b2efa2dd6ef27d78d67344db1db4915cf", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:38:54+00:00", "staged": "00001__wfv__footnotes-octet-stream-standard-name.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:35:58.417 Microsoft Word, Word found unreadable content in 00001__wfv__footnotes-octet-stream-standard-name.do … t? If you trust the source of this document, click Yes."]}
{"run": "s64b", "pass": 1, "name": "footnotes-octet-stream-bin-repeat", "sha256": "c229e9f48a63c925868434b61722d6ce1b83a3b24673454764117cafc0e56276", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:34:35+00:00", "staged": "00000__wfv__footnotes-octet-stream-bin-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:32:50.806 'Word found unreadable content in 00000__wfv__footnotes-octet-stream-bin-repeat.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 17:32:51.344 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__footnotes-octet-stream-bi...)\""]}
{"run": "s64b", "pass": 2, "name": "footnotes-octet-stream-bin-repeat", "sha256": "c229e9f48a63c925868434b61722d6ce1b83a3b24673454764117cafc0e56276", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:38:54+00:00", "staged": "00000__wfv__footnotes-octet-stream-bin-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 17:34:57.919 'Word found unreadable content in 00000__wfv__footnotes-octet-stream-bin-repeat.docx. Do you want to … ? If you trust the source of this document, click Yes.'", "2026-10-26 17:34:58.440 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__footnotes-octet-stream-bi...)\""]}
{"run": "s64b", "pass": 1, "name": "s64b-control-minimal-end", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:34:35+00:00", "staged": "00003__wfv__s64b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s64b", "pass": 2, "name": "s64b-control-minimal-end", "sha256": "5f5c12381745014425b37f497834bb11d92a86da307ccfbccb78d97c3c8826fe", "validatorRevision": "b89c953441eff860c3c46a790e4a12b472468a01", "observedAt": "2026-10-26T21:38:54+00:00", "staged": "00003__wfv__s64b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s64b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 64 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s64builder.mts`:

```ts
// Session 64 (2026-10-26): confirmations two session-63 fixes wait on.
// s64a: a notes relationship whose target escapes the package (s63c opened `../../footnotes.xml` with the note at
//       /footnotes.xml clean). Does Word stop the `..` segments at the package root?
// s64b: a notes part typed application/octet-stream (s63c refused `word/notes.bin`). Does the part's name matter?
// Every row records the validator revision it was judged at (`validatorRevision`). Helpers are copied from s62builder.mts.
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s64a pnpm exec node --import tsx s64builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, extra = "") =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${extra}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

/** The minimal parts with `word/footer1.xml` read through the section's default footer reference, holding `run`. */
const withReadFooter = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r>${run}</w:p></w:ftr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
            [CT]: overrides(parts[CT]!, ["word/footer1.xml", `${WML}.footer+xml`]),
        },
        "",
        `<w:footerReference w:type="default" r:id="rIdF"/>`,
    );

/** Two footnotes relationships in document order: word/footnotes.xml holding `first`, then word/notes2.xml (footnotes+xml) holding `second`; the body references footnote 1. */
const twoFootnotes = (first: string, second: string) => {
    const parts = withNotes("footnote", first);
    return buildDocx(
        mainWith(
            {
                ...parts,
                "word/notes2.xml": notesXml("footnote", second),
                [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "footnotes", "notes2.xml")),
                [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.footnotes+xml`]),
            },
            noteRef("footnote", "1"),
        ),
    );
};

/** Session 46's Word-saved ISO Strict fixture (pinned clean-open), with `edit` applied to its main document. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (main: string) => string = (main) => main) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    parts[MAIN] = edit(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};

/** A used `word/comments.xml` whose stored root is mc:AlternateContent; its w14 Choice holds the w:comments root with comment 0. */
const rootAlternateComments = (type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml":
                    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">` +
                    `<w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** Comment 0 (own root) with its range start inside an mc:Choice requiring `requires` (empty Fallback), the end and the reference outside. */
const splitRange = (requires: string) =>
    buildDocx(
        mainWith(
            withComments(comment("0")),
            alternate(requires, `<w:commentRangeStart w:id="0"/>`, "") +
                `<w:r><w:t>ranged</w:t></w:r><w:commentRangeEnd w:id="0"/>` +
                commentRef("0"),
        ),
    );

/** The minimal package with a reached glossary whose own sidecar relates word/glossary/footnotes.xml holding footnote `held`. */
const glossaryWithFootnotes = (held: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${TEXT_P}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "footnotes", "footnotes.xml")}</Relationships>`,
    "word/glossary/footnotes.xml": notesXml("footnote", held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(
        P[CT]!,
        ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
        ["word/glossary/footnotes.xml", `${WML}.footnotes+xml`],
    ),
});
/** Footnote 1 stored at `stored`, typed `type`, named only by a footnotes relationship with `target` and `extra`; the body references footnote 1. */
const footnotesAt = (stored: string, type: string, target: string, extra = "") =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml("footnote", "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target, extra)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef("footnote", "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const FOOTNOTES = `${WML}.footnotes+xml`;
const OCTET = "application/octet-stream";
/** Note 1 of `kind` stored at `stored`, typed `type`, named only by a `<kind>s` relationship with `target`; the body references it. */
const notesAt = (kind: Kind, stored: string, type: string, target: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, `${WML}.${kind}s+xml`]),
            },
            noteRef(kind, "1"),
        ),
    );

const chunks: Record<string, Row[]> = {
    s64a: withControls("s64a", [
        [
            "footnotes-escaping-two-levels-note-at-root-repeat",
            "repeat of s63c: the only footnotes relationship targets ../../footnotes.xml from word/; footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", FOOTNOTES, "../../footnotes.xml"),
        ],
        [
            "footnotes-escaping-two-levels-note-in-word-folder",
            "the only footnotes relationship targets ../../footnotes.xml; footnote 1 sits only in word/footnotes.xml (no /footnotes.xml)",
            () => notesAt("footnote", "word/footnotes.xml", FOOTNOTES, "../../footnotes.xml"),
        ],
        [
            "footnotes-escaping-three-levels-note-at-root",
            "the only footnotes relationship targets ../../../footnotes.xml; footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", FOOTNOTES, "../../../footnotes.xml"),
        ],
        [
            "endnotes-escaping-two-levels-note-at-root",
            "endnotes twin of s63c: the only endnotes relationship targets ../../endnotes.xml; endnote 1 sits in /endnotes.xml",
            () => notesAt("endnote", "endnotes.xml", `${WML}.endnotes+xml`, "../../endnotes.xml"),
        ],
        [
            "footnotes-one-level-note-at-root-calibration",
            "calibration: the only footnotes relationship targets ../footnotes.xml (inside the package); footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", FOOTNOTES, "../footnotes.xml"),
        ],
    ]),
    s64b: withControls("s64b", [
        [
            "footnotes-octet-stream-xml-name",
            "the only footnotes relationship names word/notes.xml, Override application/octet-stream, holding footnote 1",
            () => footnotesAt("word/notes.xml", OCTET, "notes.xml"),
        ],
        [
            "footnotes-octet-stream-standard-name",
            "the only footnotes relationship names word/footnotes.xml, Override application/octet-stream, holding footnote 1",
            () => footnotesAt("word/footnotes.xml", OCTET, "footnotes.xml"),
        ],
        [
            "footnotes-octet-stream-bin-repeat",
            "repeat of s63c: the only footnotes relationship names word/notes.bin, Override application/octet-stream, holding footnote 1",
            () => footnotesAt("word/notes.bin", OCTET, "notes.bin"),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-64 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s64a", "s64b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s64/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-64 parts of docs/plans/evidence/word-probes-2026-10-24.md into s64/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and s64/results.json from compare.py. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/Users/arthrod/temp/T/docx-validate/.scratch/word-probes")
CHUNKS = ("s64a", "s64b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s64/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 64: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "Two confirmations session 63's fixes waited on: how Word resolves a notes relationship target that escapes the package "
    "([#830](https://github.com/jandira-tech/docx-validate/issues/830)), and whether a notes part typed `application/octet-stream` "
    "defines nothing whatever its name ([#829](https://github.com/jandira-tech/docx-validate/issues/829)). Two chunks, each "
    "opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the "
    "manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    f"builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "- **Escaping targets (s64a).** With the only `footnotes` relationship targeting `../../footnotes.xml` from `word/`, Word "
    "opens the file clean when footnote 1 sits in `/footnotes.xml` (session 63's row, repeated) and offers recovery when it sits "
    "only in `word/footnotes.xml`. `../../../footnotes.xml` with the note in `/footnotes.xml`, and the endnotes twin of "
    "`../../endnotes.xml`, open clean too, as does the in-package `../footnotes.xml` calibration. Word resolves the target as "
    "RFC 3986 does, stopping `..` segments at the package root. Word-valid rejects the three clean escaping rows: three false "
    "positives.",
    "- **Octet-stream notes parts (s64b).** With the only `footnotes` relationship naming a part typed `application/octet-stream` "
    "that holds footnote 1, Word offers recovery whether the part is `word/notes.xml`, `word/footnotes.xml` or `word/notes.bin` "
    "(session 63's row, repeated). The type, not the name, makes the part define nothing. Word-valid accepts all three: three "
    "false negatives.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 64</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 64 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s64builder.mts", ROOT / "s64builder.mts", "ts"), ("compare.py", ROOT / "s64/compare.py", "python"),
                         ("section.py", ROOT / "s64/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s64/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 65: 23:08Z–23:13Z on 2026-10-26, validator columns at 1dd3500b

The Word questions the adversarial review of layers 211–216 raised ([#847](https://github.com/jandira-tech/docx-validate/issues/847), [#848](https://github.com/jandira-tech/docx-validate/issues/848), [#849](https://github.com/jandira-tech/docx-validate/issues/849)). Four chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 29 of 29 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`1dd3500b331b8a0cafa774b9dc109242222c5b9f`).

- **Nested note references (s65a, #849).** Footnote 1, whose paragraph also holds a footnote reference to 99 that no part defines, opens clean whether its notes part is reached by the escaping `../../footnotes.xml` (the note at `/footnotes.xml`) or related in-package as `word/footnotes.xml`. The endnotes twins (an endnote reference to 99 inside endnote 1) open clean too, as does the escaping calibration with no nested reference (session 64's row, repeated). Word-valid rejects both in-package rows: two false positives.
- **The read comments part typed styles (s65b–s65d, #847).** A used `word/comments.xml` typed exactly with the styles type gets the recovery offer in every shape this session stored: session 63's s63b AlternateContent root (repeated); the same with text before the `w:comments` root inside the Choice, with text in the Fallback, or with text between the Choice and the Fallback; with the Choice requiring `w` instead of `w14`; with an ISO Strict `w:comments` root inside the Choice; and with an ISO Strict root stored directly, in a Transitional package. Each matching calibration typed comments opens clean, except the text between the branches, which Word refuses typed comments too. Word-valid rejects every styles-typed row, citing session 63 or 58, and accepts the between-text calibration: one false negative.
- **A comments part with a footnote reference only a glossary defines (s65d, #848).** A comment holding a footnote reference to 1, which only the reached glossary's notes part defines, opens clean when only the main document reads the comments part, and when only the glossary reads it; read by both, it gets the recovery offer. Word-valid rejects the main-only row (a false positive) and the shared row. Session 66 separates the causes.

| Run    | Observed             | Specimen                                                | Shape                                                                                                                                                                                          | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 1dd3500b                     | strict at 1dd3500b                                                                                                                                        |
| ------ | -------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s65a` | 23:08:21Z, 23:08:34Z | `s65a-control-minimal`                                  | control                                                                                                                                                                                        | `98a6d76275a2bb1f` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65a` | 23:08:21Z, 23:08:34Z | `footnotes-escaping-nested-dangling`                    | the only footnotes relationship targets ../../footnotes.xml from word/; /footnotes.xml holds footnote 1, whose paragraph also holds a footnote reference to 99; the body references footnote 1 | `31bc40730cddb26b` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                                              |
| `s65a` | 23:08:21Z, 23:08:34Z | `footnotes-in-package-nested-dangling`                  | the same notes part as word/footnotes.xml, related in-package: footnote 1 holds a footnote reference to 99; the body references footnote 1                                                     | `348f7e65ab3543ee` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `word-footnote-reference-missing`                                                                                      |
| `s65a` | 23:08:21Z, 23:08:34Z | `endnotes-escaping-nested-dangling`                     | endnotes twin: ../../endnotes.xml; /endnotes.xml holds endnote 1, whose paragraph also holds an endnote reference to 99                                                                        | `a6f290e3ba6e1826` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                                              |
| `s65a` | 23:08:21Z, 23:08:34Z | `endnotes-in-package-nested-dangling`                   | endnotes twin, in-package word/endnotes.xml: endnote 1 holds an endnote reference to 99                                                                                                        | `f7c1796871eb13f3` | clean-open     | clean-open     | clean-open                 | invalid: `word-endnote-reference-missing`  | invalid: `paraid-missing-element`, `word-endnote-reference-missing`                                                                                       |
| `s65a` | 23:08:21Z, 23:08:34Z | `footnotes-escaping-no-nested-calibration`              | calibration (repeat of s64a): ../../footnotes.xml; /footnotes.xml holds footnote 1 and nothing else; the body references footnote 1                                                            | `bd993358479dd506` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                                              |
| `s65a` | 23:08:21Z, 23:08:34Z | `s65a-control-minimal-end`                              | control                                                                                                                                                                                        | `98a6d76275a2bb1f` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65b` | 23:08:57Z, 23:09:24Z | `s65b-control-minimal`                                  | control                                                                                                                                                                                        | `9bde15427bfaf236` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65b` | 23:08:57Z, 23:09:24Z | `comments-root-alternate-styles-s63b-repeat`            | repeat of s63b: word/comments.xml's stored root is mc:AlternateContent whose w14 Choice holds the w:comments root, Fallback empty; typed styles                                                | `cb91c163a7dc1b84` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`                                    |
| `s65b` | 23:08:57Z, 23:09:24Z | `comments-alternate-choice-text-styles`                 | s63b's shape with text before the w:comments root inside the Choice; typed styles                                                                                                              | `da7c0dbd145f7bc6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`        |
| `s65b` | 23:08:57Z, 23:09:24Z | `comments-alternate-choice-text-comments-calibration`   | calibration: the same, typed comments                                                                                                                                                          | `9404335f3fa40f0c` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`                                           |
| `s65b` | 23:08:57Z, 23:09:24Z | `comments-alternate-fallback-text-styles`               | s63b's shape with text in the Fallback; typed styles                                                                                                                                           | `9313171dd0e6469a` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`        |
| `s65b` | 23:08:57Z, 23:09:24Z | `comments-alternate-fallback-text-comments-calibration` | calibration: the same, typed comments                                                                                                                                                          | `83a9842735c95eff` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`                                           |
| `s65b` | 23:08:57Z, 23:09:24Z | `s65b-control-minimal-end`                              | control                                                                                                                                                                                        | `764f240c9c6f4840` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65c` | 23:10:27Z, 23:12:25Z | `s65c-control-minimal`                                  | control                                                                                                                                                                                        | `764f240c9c6f4840` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-between-text-styles`                | s63b's shape with text between the Choice and the Fallback; typed styles                                                                                                                       | `a1cff64f1edf12ef` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`        |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-between-text-comments-calibration`  | calibration: the same, typed comments                                                                                                                                                          | `ca6f47a1785d5ef4` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`                                           |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-requires-w-styles`                  | s63b's shape with the Choice requiring w (the WordprocessingML main namespace) instead of w14; typed styles                                                                                    | `61737bfdc9ebefe7` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`                                                     |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-requires-w-comments-calibration`    | calibration: the same, typed comments                                                                                                                                                          | `9a7f859bf776c6f4` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                                                                        |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-strict-root-styles`                 | s63b's shape with an ISO Strict w:comments root in the Choice (Transitional main document); typed styles                                                                                       | `693fab1366b18a6c` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`        |
| `s65c` | 23:10:27Z, 23:12:25Z | `comments-alternate-strict-root-comments-calibration`   | calibration: the same, typed comments                                                                                                                                                          | `e2f0a2d9ac7dd3e1` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error`                                           |
| `s65c` | 23:10:27Z, 23:12:25Z | `s65c-control-minimal-end`                              | control                                                                                                                                                                                        | `764f240c9c6f4840` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65d` | 23:12:59Z, 23:13:34Z | `s65d-control-minimal`                                  | control                                                                                                                                                                                        | `764f240c9c6f4840` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s65d` | 23:12:59Z, 23:13:34Z | `comments-strict-root-styles`                           | word/comments.xml's stored root is an ISO Strict w:comments (Transitional main document); typed styles                                                                                         | `decae62819f72270` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `comment-thread-count-mismatch`, `paraid-missing-element`                                                     |
| `s65d` | 23:12:59Z, 23:13:34Z | `comments-strict-root-comments-calibration`             | calibration: the same, typed comments                                                                                                                                                          | `11aea989e4cfbfaa` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`                                                                                        |
| `s65d` | 23:12:59Z, 23:13:34Z | `comments-footnote-glossary-only-main-reach`            | word/comments.xml, read by the main document only, holds a footnote reference to 1; only the reached glossary's notes part defines footnote 1                                                  | `4bf6c361bb811389` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing` |
| `s65d` | 23:12:59Z, 23:13:34Z | `comments-footnote-glossary-only-glossary-reach`        | the same comments part read by the glossary only (its docPart references comment 0; its sidecar relates ../comments.xml)                                                                       | `3f301c8e5ee478bd` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `paraid-missing-element`                                    |
| `s65d` | 23:12:59Z, 23:13:34Z | `comments-footnote-glossary-only-both-reaches`          | the same comments part read by both the main document and the glossary                                                                                                                         | `acb8ee294d8ce6ec` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing` |
| `s65d` | 23:12:59Z, 23:13:34Z | `s65d-control-minimal-end`                              | control                                                                                                                                                                                        | `764f240c9c6f4840` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |

<details><summary>Raw records, session 65</summary>

```jsonl
{"run": "s65a", "pass": 1, "name": "s65a-control-minimal", "sha256": "98a6d76275a2bb1f530e3ba0c8ac668aa22d10d3d8aafd6db64c510d4f9af532", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00006__wfv__s65a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "s65a-control-minimal", "sha256": "98a6d76275a2bb1f530e3ba0c8ac668aa22d10d3d8aafd6db64c510d4f9af532", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00006__wfv__s65a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "footnotes-escaping-nested-dangling", "sha256": "31bc40730cddb26bd6a8eadcb70398f6303909ba0c0e56c13276703cecf5ea82", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00002__wfv__footnotes-escaping-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-nested-dangling_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "footnotes-escaping-nested-dangling", "sha256": "31bc40730cddb26bd6a8eadcb70398f6303909ba0c0e56c13276703cecf5ea82", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00002__wfv__footnotes-escaping-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-nested-dangling_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "footnotes-in-package-nested-dangling", "sha256": "348f7e65ab3543ee4dce93adf420b3e8da54812e330141c6e0e92f678cd47efd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00004__wfv__footnotes-in-package-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-in-package-nested-dangling_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "footnotes-in-package-nested-dangling", "sha256": "348f7e65ab3543ee4dce93adf420b3e8da54812e330141c6e0e92f678cd47efd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00004__wfv__footnotes-in-package-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-in-package-nested-dangling_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "endnotes-escaping-nested-dangling", "sha256": "a6f290e3ba6e1826811f3d45216bcabb28de95de8ac66f043300787c14fb0e3a", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00000__wfv__endnotes-escaping-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-escaping-nested-dangling_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "endnotes-escaping-nested-dangling", "sha256": "a6f290e3ba6e1826811f3d45216bcabb28de95de8ac66f043300787c14fb0e3a", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00000__wfv__endnotes-escaping-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-escaping-nested-dangling_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "endnotes-in-package-nested-dangling", "sha256": "f7c1796871eb13f3f2b5bd24838b526ac187821084917fecbb3ac803ab697323", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00001__wfv__endnotes-in-package-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-in-package-nested-dangling_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "endnotes-in-package-nested-dangling", "sha256": "f7c1796871eb13f3f2b5bd24838b526ac187821084917fecbb3ac803ab697323", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00001__wfv__endnotes-in-package-nested-dangling.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-in-package-nested-dangling_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "footnotes-escaping-no-nested-calibration", "sha256": "bd993358479dd506f9767c0dd1c7a7d0611381ad11145a0fbfe63778531540f9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00003__wfv__footnotes-escaping-no-nested-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-no-nested-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "footnotes-escaping-no-nested-calibration", "sha256": "bd993358479dd506f9767c0dd1c7a7d0611381ad11145a0fbfe63778531540f9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00003__wfv__footnotes-escaping-no-nested-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-escaping-no-nested-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 1, "name": "s65a-control-minimal-end", "sha256": "98a6d76275a2bb1f530e3ba0c8ac668aa22d10d3d8aafd6db64c510d4f9af532", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:21+00:00", "staged": "00005__wfv__s65a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65a", "pass": 2, "name": "s65a-control-minimal-end", "sha256": "98a6d76275a2bb1f530e3ba0c8ac668aa22d10d3d8aafd6db64c510d4f9af532", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:34+00:00", "staged": "00005__wfv__s65a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 1, "name": "s65b-control-minimal", "sha256": "9bde15427bfaf236fbab4a4bfc5c07d81056fe92ab5a51283107efb01ee3d2cb", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00006__wfv__s65b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 2, "name": "s65b-control-minimal", "sha256": "9bde15427bfaf236fbab4a4bfc5c07d81056fe92ab5a51283107efb01ee3d2cb", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00006__wfv__s65b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 1, "name": "comments-root-alternate-styles-s63b-repeat", "sha256": "cb91c163a7dc1b84d6e0aaede6aa7d7826a09908f471143497a57548285488d5", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00004__wfv__comments-root-alternate-styles-s63b-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:08:55.507 'Word found unreadable content in 00004__wfv__comments-root-alternate-styles-s63b-repeat.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:08:56.275 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__comments-root-alternate-s...)\""]}
{"run": "s65b", "pass": 2, "name": "comments-root-alternate-styles-s63b-repeat", "sha256": "cb91c163a7dc1b84d6e0aaede6aa7d7826a09908f471143497a57548285488d5", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00004__wfv__comments-root-alternate-styles-s63b-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:22.988 'Word found unreadable content in 00004__wfv__comments-root-alternate-styles-s63b-repeat.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:23.869 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__comments-root-alternate-s...)\""]}
{"run": "s65b", "pass": 1, "name": "comments-alternate-choice-text-styles", "sha256": "da7c0dbd145f7bc64ffd71d08eb713a24fd273ec67a2db2561fde3d8bbb33ea7", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00001__wfv__comments-alternate-choice-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:08:47.225 'Word found unreadable content in 00001__wfv__comments-alternate-choice-text-styles.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:08:48.093 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-alternate-choice...)\""]}
{"run": "s65b", "pass": 2, "name": "comments-alternate-choice-text-styles", "sha256": "da7c0dbd145f7bc64ffd71d08eb713a24fd273ec67a2db2561fde3d8bbb33ea7", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00001__wfv__comments-alternate-choice-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:11.618 'Word found unreadable content in 00001__wfv__comments-alternate-choice-text-styles.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:12.526 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-alternate-choice...)\""]}
{"run": "s65b", "pass": 1, "name": "comments-alternate-choice-text-comments-calibration", "sha256": "9404335f3fa40f0cd1eb128179d0121a549d2e65eab92fbc234d2be626e1e33a", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00000__wfv__comments-alternate-choice-text-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-choice-text-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 2, "name": "comments-alternate-choice-text-comments-calibration", "sha256": "9404335f3fa40f0cd1eb128179d0121a549d2e65eab92fbc234d2be626e1e33a", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00000__wfv__comments-alternate-choice-text-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-choice-text-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 1, "name": "comments-alternate-fallback-text-styles", "sha256": "9313171dd0e6469aecab9c53495674fc9dc59640e8e5dd0f6528db2cd9658f7f", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00003__wfv__comments-alternate-fallback-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:08:51.357 'Word found unreadable content in 00003__wfv__comments-alternate-fallback-text-styles.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:08:52.126 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__comments-alternate-fallba...)\""]}
{"run": "s65b", "pass": 2, "name": "comments-alternate-fallback-text-styles", "sha256": "9313171dd0e6469aecab9c53495674fc9dc59640e8e5dd0f6528db2cd9658f7f", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00003__wfv__comments-alternate-fallback-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:17.612 'Word found unreadable content in 00003__wfv__comments-alternate-fallback-text-styles.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:18.510 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__comments-alternate-fallba...)\""]}
{"run": "s65b", "pass": 1, "name": "comments-alternate-fallback-text-comments-calibration", "sha256": "83a9842735c95eff934697f492de73fdded70b91e335edbab5f17c00e3c282b8", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00002__wfv__comments-alternate-fallback-text-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-fallback-text-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 2, "name": "comments-alternate-fallback-text-comments-calibration", "sha256": "83a9842735c95eff934697f492de73fdded70b91e335edbab5f17c00e3c282b8", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00002__wfv__comments-alternate-fallback-text-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-fallback-text-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 1, "name": "s65b-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:08:57+00:00", "staged": "00005__wfv__s65b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65b", "pass": 2, "name": "s65b-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:09:24+00:00", "staged": "00005__wfv__s65b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 1, "name": "s65c-control-minimal", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00007__wfv__s65c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 2, "name": "s65c-control-minimal", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00007__wfv__s65c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-between-text-styles", "sha256": "a1cff64f1edf12efe3e2a19d82ec3d56c4d1eadc02fb18611c9e3bd3093e6520", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00001__wfv__comments-alternate-between-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:41.657 'Word found unreadable content in 00001__wfv__comments-alternate-between-text-styles.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:42.409 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-alternate-betwee...)\""]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-between-text-styles", "sha256": "a1cff64f1edf12efe3e2a19d82ec3d56c4d1eadc02fb18611c9e3bd3093e6520", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00001__wfv__comments-alternate-between-text-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:11:35.080 Microsoft Word, Word found unreadable content in 00001__wfv__comments-alternate-between-text-styles. … t? If you trust the source of this document, click Yes.", "2026-10-26 19:11:35.730 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-alternate-betwee...)\""]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-between-text-comments-calibration", "sha256": "ca6f47a1785d5ef4c03ba95ab89858453d8472a33939de7bc7c74e0c11ad700d", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00000__wfv__comments-alternate-between-text-comments-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:37.474 'Word found unreadable content in 00000__wfv__comments-alternate-between-text-comments-calibra.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:38.081 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-alternate-betwee...)\""]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-between-text-comments-calibration", "sha256": "ca6f47a1785d5ef4c03ba95ab89858453d8472a33939de7bc7c74e0c11ad700d", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00000__wfv__comments-alternate-between-text-comments-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:10:43.207 'Word found unreadable content in 00000__wfv__comments-alternate-between-text-comments-calibra.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:10:43.798 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-alternate-betwee...)\""]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-requires-w-styles", "sha256": "61737bfdc9ebefe7d8cafe7002e8add8a3667296c53b4f5b84a9606fe26f7abd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00003__wfv__comments-alternate-requires-w-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:45.986 'Word found unreadable content in 00003__wfv__comments-alternate-requires-w-styles.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:46.843 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__comments-alternate-requir...)\""]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-requires-w-styles", "sha256": "61737bfdc9ebefe7d8cafe7002e8add8a3667296c53b4f5b84a9606fe26f7abd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00003__wfv__comments-alternate-requires-w-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:11:49.213 \"Word found unreadable content in 00003__wfv__comments-alternate-requires-w-styles.docx. Do you want … ? If you trust the source of this document, click Yes.\""]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-requires-w-comments-calibration", "sha256": "9a7f859bf776c6f428a30623e3db9288f36940b64afb7fe1ba0464d500e80c00", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00002__wfv__comments-alternate-requires-w-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-requires-w-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-requires-w-comments-calibration", "sha256": "9a7f859bf776c6f428a30623e3db9288f36940b64afb7fe1ba0464d500e80c00", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00002__wfv__comments-alternate-requires-w-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-requires-w-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-strict-root-styles", "sha256": "693fab1366b18a6c0ea150f6c7cab62a7a626e6ff44e9a7eabd60f6fabf8eff7", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00005__wfv__comments-alternate-strict-root-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:09:51.577 'Word found unreadable content in 00005__wfv__comments-alternate-strict-root-styles.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:09:52.532 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__comments-alternate-strict...)\""]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-strict-root-styles", "sha256": "693fab1366b18a6c0ea150f6c7cab62a7a626e6ff44e9a7eabd60f6fabf8eff7", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00005__wfv__comments-alternate-strict-root-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:12:03.305 \"Word found unreadable content in 00005__wfv__comments-alternate-strict-root-styles.docx. Do you wan … ? If you trust the source of this document, click Yes.\""]}
{"run": "s65c", "pass": 1, "name": "comments-alternate-strict-root-comments-calibration", "sha256": "e2f0a2d9ac7dd3e19f976e3c9211b8ce8253ce79962f3f3a7082f70ae090a373", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00004__wfv__comments-alternate-strict-root-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-strict-root-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 2, "name": "comments-alternate-strict-root-comments-calibration", "sha256": "e2f0a2d9ac7dd3e19f976e3c9211b8ce8253ce79962f3f3a7082f70ae090a373", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00004__wfv__comments-alternate-strict-root-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-strict-root-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 1, "name": "s65c-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:10:27+00:00", "staged": "00006__wfv__s65c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65c", "pass": 2, "name": "s65c-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:25+00:00", "staged": "00006__wfv__s65c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 1, "name": "s65d-control-minimal", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00006__wfv__s65d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 2, "name": "s65d-control-minimal", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00006__wfv__s65d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 1, "name": "comments-strict-root-styles", "sha256": "decae62819f72270722655e999873bcd3b4f2f6651e2aa75d6f098db4a255e7c", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00004__wfv__comments-strict-root-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:12:58.882 \"Word found unreadable content in 00004__wfv__comments-strict-root-styles.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s65d", "pass": 2, "name": "comments-strict-root-styles", "sha256": "decae62819f72270722655e999873bcd3b4f2f6651e2aa75d6f098db4a255e7c", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00004__wfv__comments-strict-root-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:13:34.149 \"Word found unreadable content in 00004__wfv__comments-strict-root-styles.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s65d", "pass": 1, "name": "comments-strict-root-comments-calibration", "sha256": "11aea989e4cfbfaa0491149e3e54e0d2b81ca1c1c04731c5f4da3eecc47828f6", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00003__wfv__comments-strict-root-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-strict-root-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 2, "name": "comments-strict-root-comments-calibration", "sha256": "11aea989e4cfbfaa0491149e3e54e0d2b81ca1c1c04731c5f4da3eecc47828f6", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00003__wfv__comments-strict-root-comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-strict-root-comments-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 1, "name": "comments-footnote-glossary-only-main-reach", "sha256": "4bf6c361bb811389ed523d8025c2fb9ba8918cb31d0d7b5b8875ef7a07188b4b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00002__wfv__comments-footnote-glossary-only-main-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footnote-glossary-only-main-reach_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 2, "name": "comments-footnote-glossary-only-main-reach", "sha256": "4bf6c361bb811389ed523d8025c2fb9ba8918cb31d0d7b5b8875ef7a07188b4b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00002__wfv__comments-footnote-glossary-only-main-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footnote-glossary-only-main-reach_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 1, "name": "comments-footnote-glossary-only-glossary-reach", "sha256": "3f301c8e5ee478bdea5660ff494782684a0d3480b970425e712917735fd465f3", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00001__wfv__comments-footnote-glossary-only-glossary-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footnote-glossary-only-glossary-reach_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 2, "name": "comments-footnote-glossary-only-glossary-reach", "sha256": "3f301c8e5ee478bdea5660ff494782684a0d3480b970425e712917735fd465f3", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00001__wfv__comments-footnote-glossary-only-glossary-reach.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footnote-glossary-only-glossary-reach_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 1, "name": "comments-footnote-glossary-only-both-reaches", "sha256": "acb8ee294d8ce6ec0a43225382b672d56eb8227c812a5827ac6b7ce86f950112", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00000__wfv__comments-footnote-glossary-only-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:12:41.558 'Word found unreadable content in 00000__wfv__comments-footnote-glossary-only-both-reaches.docx. Do  … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:12:42.195 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-footnote-glossar...)\""]}
{"run": "s65d", "pass": 2, "name": "comments-footnote-glossary-only-both-reaches", "sha256": "acb8ee294d8ce6ec0a43225382b672d56eb8227c812a5827ac6b7ce86f950112", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00000__wfv__comments-footnote-glossary-only-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:13:16.892 'Word found unreadable content in 00000__wfv__comments-footnote-glossary-only-both-reaches.docx. Do  … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:13:17.496 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-footnote-glossar...)\""]}
{"run": "s65d", "pass": 1, "name": "s65d-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:12:59+00:00", "staged": "00005__wfv__s65d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s65d", "pass": 2, "name": "s65d-control-minimal-end", "sha256": "764f240c9c6f484011b3d6179662a2b2509f872fe5d1f92616d6a1f7d8f6d8e4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:13:34+00:00", "staged": "00005__wfv__s65d-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s65d-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 65 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s65builder.mts`:

```ts
// Session 65 (2026-10-26): questions the adversarial review of layers 211-216 raised.
// s65a: a dangling note reference inside a notes part, reached by an escaping target or in-package (#849).
// s65b, s65c, s65d: s63b's AlternateContent comments root with text in it, a non-w14 Choice or a Strict root, and a Strict
//       root stored directly, each typed styles beside a typed-comments calibration (#847); a comments part holding a
//       footnote reference only a glossary's notes define, read by the main document, a glossary or both (#848).
// Every row records the validator revision it was judged at (`validatorRevision`). Helpers are copied from s64builder.mts.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s65a pnpm exec node --import tsx s65builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const WS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, extra = "") =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${extra}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

/** The minimal parts with `word/footer1.xml` read through the section's default footer reference, holding `run`. */
const withReadFooter = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r>${run}</w:p></w:ftr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
            [CT]: overrides(parts[CT]!, ["word/footer1.xml", `${WML}.footer+xml`]),
        },
        "",
        `<w:footerReference w:type="default" r:id="rIdF"/>`,
    );

/** Two footnotes relationships in document order: word/footnotes.xml holding `first`, then word/notes2.xml (footnotes+xml) holding `second`; the body references footnote 1. */
const twoFootnotes = (first: string, second: string) => {
    const parts = withNotes("footnote", first);
    return buildDocx(
        mainWith(
            {
                ...parts,
                "word/notes2.xml": notesXml("footnote", second),
                [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "footnotes", "notes2.xml")),
                [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.footnotes+xml`]),
            },
            noteRef("footnote", "1"),
        ),
    );
};

/** Session 46's Word-saved ISO Strict fixture (pinned clean-open), with `edit` applied to its main document. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (main: string) => string = (main) => main) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    parts[MAIN] = edit(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};

/** A used `word/comments.xml` whose stored root is mc:AlternateContent; its w14 Choice holds the w:comments root with comment 0. */
const rootAlternateComments = (type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml":
                    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">` +
                    `<w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** Comment 0 (own root) with its range start inside an mc:Choice requiring `requires` (empty Fallback), the end and the reference outside. */
const splitRange = (requires: string) =>
    buildDocx(
        mainWith(
            withComments(comment("0")),
            alternate(requires, `<w:commentRangeStart w:id="0"/>`, "") +
                `<w:r><w:t>ranged</w:t></w:r><w:commentRangeEnd w:id="0"/>` +
                commentRef("0"),
        ),
    );

/** The minimal package with a reached glossary whose own sidecar relates word/glossary/footnotes.xml holding footnote `held`. */
const glossaryWithFootnotes = (held: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${TEXT_P}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "footnotes", "footnotes.xml")}</Relationships>`,
    "word/glossary/footnotes.xml": notesXml("footnote", held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(
        P[CT]!,
        ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
        ["word/glossary/footnotes.xml", `${WML}.footnotes+xml`],
    ),
});
/** Footnote 1 stored at `stored`, typed `type`, named only by a footnotes relationship with `target` and `extra`; the body references footnote 1. */
const footnotesAt = (stored: string, type: string, target: string, extra = "") =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml("footnote", "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target, extra)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef("footnote", "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const FOOTNOTES = `${WML}.footnotes+xml`;
const STYLES = `${WML}.styles+xml`;
const COMMENTS = `${WML}.comments+xml`;
/** Note 1 of `kind` stored at `stored`, typed `type`, named only by a `<kind>s` relationship with `target`; the body references it. */
const notesAt = (kind: Kind, stored: string, type: string, target: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef(kind, "1"),
        ),
    );
/** Note 1 of `kind` stored at `stored` (its paragraph also holding `nested`), named only by a `<kind>s` relationship with `target`; the body references note 1. */
const notesWithNested = (kind: Kind, stored: string, target: string, nested: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="1"><w:p><w:r><w:t>Text</w:t></w:r>${nested}</w:p></w:${kind}></w:${kind}s>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, `${WML}.${kind}s+xml`]),
            },
            noteRef(kind, "1"),
        ),
    );
/** A used `word/comments.xml` stored as `stored` and typed `type`; the body references comment 0. */
const usedComments = (stored: string, type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml": stored,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** s63b's stored root (an mc:AlternateContent whose Choice holds the w:comments root) with `edit` applied: text before the root, a non-empty Fallback, text between the branches, another Requires, or a Strict root. */
const alternateCommentsRoot = ({ before = "", fallback = "", between = "", requires = "w14", rootNs = W } = {}) =>
    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"${requires === "w" ? ` xmlns:w="${W}"` : ""}><mc:Choice Requires="${requires}">` +
    `${before}<w:comments xmlns:w="${rootNs}">${comment("0")}</w:comments></mc:Choice>${between}` +
    (fallback ? `<mc:Fallback>${fallback}</mc:Fallback>` : "<mc:Fallback/>") +
    "</mc:AlternateContent>";
/** A reached glossary relating its own word/glossary/footnotes.xml (footnote 1), plus word/comments.xml whose comment 0 holds a footnote reference to 1, read by the main document, the glossary or both. */
const sharedComments = (main: boolean, glossary: boolean) => {
    const parts = glossaryWithFootnotes("1");
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Text</w:t></w:r>${noteRef("footnote", "1")}</w:p></w:comment></w:comments>`,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", COMMENTS]),
    };
    if (glossary) {
        next["word/glossary/document.xml"] = replaceOnce(
            next["word/glossary/document.xml"]!,
            "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
            `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${commentRef("0")}</w:p>`,
        );
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    }
    if (!main) return buildDocx(next);
    return buildDocx(
        mainWith({ ...next, [SIDECAR]: appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")) }, commentRef("0")),
    );
};

const chunks: Record<string, Row[]> = {
    s65a: withControls("s65a", [
        [
            "footnotes-escaping-nested-dangling",
            "the only footnotes relationship targets ../../footnotes.xml from word/; /footnotes.xml holds footnote 1, whose paragraph also holds a footnote reference to 99; the body references footnote 1",
            () => notesWithNested("footnote", "footnotes.xml", "../../footnotes.xml", noteRef("footnote", "99")),
        ],
        [
            "footnotes-in-package-nested-dangling",
            "the same notes part as word/footnotes.xml, related in-package: footnote 1 holds a footnote reference to 99; the body references footnote 1",
            () => notesWithNested("footnote", "word/footnotes.xml", "footnotes.xml", noteRef("footnote", "99")),
        ],
        [
            "endnotes-escaping-nested-dangling",
            "endnotes twin: ../../endnotes.xml; /endnotes.xml holds endnote 1, whose paragraph also holds an endnote reference to 99",
            () => notesWithNested("endnote", "endnotes.xml", "../../endnotes.xml", noteRef("endnote", "99")),
        ],
        [
            "endnotes-in-package-nested-dangling",
            "endnotes twin, in-package word/endnotes.xml: endnote 1 holds an endnote reference to 99",
            () => notesWithNested("endnote", "word/endnotes.xml", "endnotes.xml", noteRef("endnote", "99")),
        ],
        [
            "footnotes-escaping-no-nested-calibration",
            "calibration (repeat of s64a): ../../footnotes.xml; /footnotes.xml holds footnote 1 and nothing else; the body references footnote 1",
            () => notesAt("footnote", "footnotes.xml", FOOTNOTES, "../../footnotes.xml"),
        ],
    ]),
    s65b: withControls("s65b", [
        [
            "comments-root-alternate-styles-s63b-repeat",
            "repeat of s63b: word/comments.xml's stored root is mc:AlternateContent whose w14 Choice holds the w:comments root, Fallback empty; typed styles",
            () => rootAlternateComments(STYLES),
        ],
        [
            "comments-alternate-choice-text-styles",
            "s63b's shape with text before the w:comments root inside the Choice; typed styles",
            () => usedComments(alternateCommentsRoot({ before: "NOT-A-ROOT" }), STYLES),
        ],
        [
            "comments-alternate-choice-text-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(alternateCommentsRoot({ before: "NOT-A-ROOT" }), COMMENTS),
        ],
        [
            "comments-alternate-fallback-text-styles",
            "s63b's shape with text in the Fallback; typed styles",
            () => usedComments(alternateCommentsRoot({ fallback: "NOT-EMPTY" }), STYLES),
        ],
        [
            "comments-alternate-fallback-text-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(alternateCommentsRoot({ fallback: "NOT-EMPTY" }), COMMENTS),
        ],
    ]),
    s65c: withControls("s65c", [
        [
            "comments-alternate-between-text-styles",
            "s63b's shape with text between the Choice and the Fallback; typed styles",
            () => usedComments(alternateCommentsRoot({ between: "NOT-A-BRANCH" }), STYLES),
        ],
        [
            "comments-alternate-between-text-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(alternateCommentsRoot({ between: "NOT-A-BRANCH" }), COMMENTS),
        ],
        [
            "comments-alternate-requires-w-styles",
            "s63b's shape with the Choice requiring w (the WordprocessingML main namespace) instead of w14; typed styles",
            () => usedComments(alternateCommentsRoot({ requires: "w" }), STYLES),
        ],
        [
            "comments-alternate-requires-w-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(alternateCommentsRoot({ requires: "w" }), COMMENTS),
        ],
        [
            "comments-alternate-strict-root-styles",
            "s63b's shape with an ISO Strict w:comments root in the Choice (Transitional main document); typed styles",
            () => usedComments(alternateCommentsRoot({ rootNs: WS }), STYLES),
        ],
        [
            "comments-alternate-strict-root-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(alternateCommentsRoot({ rootNs: WS }), COMMENTS),
        ],
    ]),
    s65d: withControls("s65d", [
        [
            "comments-strict-root-styles",
            "word/comments.xml's stored root is an ISO Strict w:comments (Transitional main document); typed styles",
            () => usedComments(`${XML_DECL}<w:comments xmlns:w="${WS}">${comment("0")}</w:comments>`, STYLES),
        ],
        [
            "comments-strict-root-comments-calibration",
            "calibration: the same, typed comments",
            () => usedComments(`${XML_DECL}<w:comments xmlns:w="${WS}">${comment("0")}</w:comments>`, COMMENTS),
        ],
        [
            "comments-footnote-glossary-only-main-reach",
            "word/comments.xml, read by the main document only, holds a footnote reference to 1; only the reached glossary's notes part defines footnote 1",
            () => sharedComments(true, false),
        ],
        [
            "comments-footnote-glossary-only-glossary-reach",
            "the same comments part read by the glossary only (its docPart references comment 0; its sidecar relates ../comments.xml)",
            () => sharedComments(false, true),
        ],
        [
            "comments-footnote-glossary-only-both-reaches",
            "the same comments part read by both the main document and the glossary",
            () => sharedComments(true, true),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
writeFileSync(path.join(dir, "..", "specimens.jsonl"), "");
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-65 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s65a", "s65b", "s65c", "s65d")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s65/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-65 parts of docs/plans/evidence/word-probes-2026-10-24.md into s65/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s65a", "s65b", "s65c", "s65d")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s65/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 65: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "The Word questions the adversarial review of layers 211–216 raised ([#847](https://github.com/jandira-tech/docx-validate/issues/847), [#848](https://github.com/jandira-tech/docx-validate/issues/848), "
    "[#849](https://github.com/jandira-tech/docx-validate/issues/849)). Four chunks, each "
    "opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the "
    "manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    f"builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "- **Nested note references (s65a, #849).** Footnote 1, whose paragraph also holds a footnote reference to 99 that no part "
    "defines, opens clean whether its notes part is reached by the escaping `../../footnotes.xml` (the note at `/footnotes.xml`) "
    "or related in-package as `word/footnotes.xml`. The endnotes twins (an endnote reference to 99 inside endnote 1) open clean "
    "too, as does the escaping calibration with no nested reference (session 64's row, repeated). Word-valid rejects both "
    "in-package rows: two false positives.",
    "- **The read comments part typed styles (s65b–s65d, #847).** A used `word/comments.xml` typed exactly with the styles type "
    "gets the recovery offer in every shape this session stored: session 63's s63b AlternateContent root (repeated); the same "
    "with text before the `w:comments` root inside the Choice, with text in the Fallback, or with text between the Choice and "
    "the Fallback; with the Choice requiring `w` instead of `w14`; with an ISO Strict `w:comments` root inside the Choice; and "
    "with an ISO Strict root stored directly, in a Transitional package. Each matching calibration typed comments opens clean, "
    "except the text between the branches, which Word refuses typed comments too. Word-valid rejects every styles-typed row, "
    "citing session 63 or 58, and accepts the between-text calibration: one false negative.",
    "- **A comments part with a footnote reference only a glossary defines (s65d, #848).** A comment holding a footnote "
    "reference to 1, which only the reached glossary's notes part defines, opens clean when only the main document reads the "
    "comments part, and when only the glossary reads it; read by both, it gets the recovery offer. Word-valid rejects the "
    "main-only row (a false positive) and the shared row. Session 66 separates the causes.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 65</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 65 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s65builder.mts", ROOT / "s65builder.mts", "ts"), ("compare.py", ROOT / "s65/compare.py", "python"),
                         ("section.py", ROOT / "s65/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s65/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 66: 23:17Z–23:21Z on 2026-10-26, validator columns at 1dd3500b

Calibrations for session 65's surprises. One chunk, opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 8 of 8 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`1dd3500b331b8a0cafa774b9dc109242222c5b9f`).

- **A comments part both the main document and a glossary read (s66a).** With no note reference at all, a `word/comments.xml` that both the main document and a reached glossary relate and reference gets the recovery offer, so the shared reach, not the note reference, is what Word refused in s65d (that row, repeated, is refused again). Word-valid accepts the calibration: a false negative.
- **Dangling footnote references in comments (s66a).** With no footnotes part anywhere, a comment holding a footnote reference to 99 opens clean when only the main document, or only the glossary, reads the comments part; read by both, it gets the recovery offer, as the shared reach does without the reference. Word-valid rejects all three: the two single-reach rows are false positives.
- **A footnote reference inside an endnotes part (s66a).** Endnote 1 holding a footnote reference to 99, with no footnotes part, opens clean. With session 16's endnote reference inside footnotes and session 65's same-kind rows, every nesting of a note reference in a notes part that these sessions stored opens clean. Word-valid rejects this row: a false positive.

| Run    | Observed             | Specimen                                              | Shape                                                                                                                                                              | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 1dd3500b                     | strict at 1dd3500b                                                                                                                                        |
| ------ | -------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s66a` | 23:17:58Z, 23:21:10Z | `s66a-control-minimal`                                | control                                                                                                                                                            | `27fbf3b06ebb5498` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |
| `s66a` | 23:17:58Z, 23:21:10Z | `comments-both-reaches-no-note-reference`             | calibration for s65d: word/comments.xml read by both the main document and a reached glossary; comment 0 holds no note reference                                   | `09c8752902b90b70` | repair-warning | repair-warning | unreadable-content-warning | valid                                      | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`                                                              |
| `s66a` | 23:17:58Z, 23:21:10Z | `comments-footnote-glossary-only-both-reaches-repeat` | repeat of s65d: the same shared comments part, comment 0 holding a footnote reference to 1 that only the glossary's notes part defines                             | `9610d3c705316d6c` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing` |
| `s66a` | 23:17:58Z, 23:21:10Z | `comments-main-reach-dangling-footnote-no-notes`      | word/comments.xml read by the main document only; comment 0 holds a footnote reference to 99; no part anywhere defines a footnote (the glossary has no notes part) | `f3ea7d981dec862b` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `rels-empty-part`, `word-footnote-reference-missing`        |
| `s66a` | 23:17:58Z, 23:21:10Z | `comments-glossary-reach-dangling-footnote-no-notes`  | the same comments part read by the glossary only; no part defines a footnote                                                                                       | `ee62b61a08118e91` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing`                           |
| `s66a` | 23:17:58Z, 23:21:10Z | `comments-both-reaches-dangling-footnote-no-notes`    | the same comments part read by both; no part defines a footnote                                                                                                    | `72b98cefa6e9ac28` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`, `word-footnote-reference-missing`                           |
| `s66a` | 23:17:58Z, 23:21:10Z | `endnotes-in-package-nested-dangling-footnote`        | word/endnotes.xml, related in-package: endnote 1 holds a footnote reference to 99 (no footnotes part); the body references endnote 1                               | `b127fb1716b4207d` | clean-open     | clean-open     | clean-open                 | invalid: `word-footnote-reference-missing` | invalid: `paraid-missing-element`, `word-footnote-reference-missing`                                                                                      |
| `s66a` | 23:17:58Z, 23:21:10Z | `s66a-control-minimal-end`                            | control                                                                                                                                                            | `27fbf3b06ebb5498` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                                                     |

<details><summary>Raw records, session 66</summary>

```jsonl
{"run": "s66a", "pass": 1, "name": "s66a-control-minimal", "sha256": "27fbf3b06ebb5498f493ac924f7cf9843c8e6ff476b8d52a72c894b1d9c3acd9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00007__wfv__s66a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s66a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 2, "name": "s66a-control-minimal", "sha256": "27fbf3b06ebb5498f493ac924f7cf9843c8e6ff476b8d52a72c894b1d9c3acd9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00007__wfv__s66a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s66a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 1, "name": "comments-both-reaches-no-note-reference", "sha256": "09c8752902b90b702c9f397026581f27e1e490794023e6594144e2f7d6a2ab48", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00001__wfv__comments-both-reaches-no-note-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:16:11.967 Microsoft Word, Word found unreadable content in 00001__wfv__comments-both-reaches-no-note-reference … t? If you trust the source of this document, click Yes.", "2026-10-26 19:16:12.665 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-both-reaches-no-...)\""]}
{"run": "s66a", "pass": 2, "name": "comments-both-reaches-no-note-reference", "sha256": "09c8752902b90b702c9f397026581f27e1e490794023e6594144e2f7d6a2ab48", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00001__wfv__comments-both-reaches-no-note-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:19:21.817 Microsoft Word, Word found unreadable content in 00001__wfv__comments-both-reaches-no-note-reference … t? If you trust the source of this document, click Yes.", "2026-10-26 19:19:22.514 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-both-reaches-no-...)\""]}
{"run": "s66a", "pass": 1, "name": "comments-footnote-glossary-only-both-reaches-repeat", "sha256": "9610d3c705316d6c6532dd9e09b5e55e65b4f5ec5a8a81e68b0393ee09872504", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00002__wfv__comments-footnote-glossary-only-both-reaches-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:17:00.579 Microsoft Word, Word found unreadable content in 00002__wfv__comments-footnote-glossary-only-both-re … t? If you trust the source of this document, click Yes.", "2026-10-26 19:17:01.264 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__comments-footnote-glossar...)\""]}
{"run": "s66a", "pass": 2, "name": "comments-footnote-glossary-only-both-reaches-repeat", "sha256": "9610d3c705316d6c6532dd9e09b5e55e65b4f5ec5a8a81e68b0393ee09872504", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00002__wfv__comments-footnote-glossary-only-both-reaches-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:20:05.837 Microsoft Word, Word found unreadable content in 00002__wfv__comments-footnote-glossary-only-both-re … t? If you trust the source of this document, click Yes."]}
{"run": "s66a", "pass": 1, "name": "comments-main-reach-dangling-footnote-no-notes", "sha256": "f3ea7d981dec862bb933c0b06d05efc6daef7ac9c4506fab296b4910e7f7d344", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00004__wfv__comments-main-reach-dangling-footnote-no-notes.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-main-reach-dangling-footnote-no-notes_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 2, "name": "comments-main-reach-dangling-footnote-no-notes", "sha256": "f3ea7d981dec862bb933c0b06d05efc6daef7ac9c4506fab296b4910e7f7d344", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00004__wfv__comments-main-reach-dangling-footnote-no-notes.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-main-reach-dangling-footnote-no-notes_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 1, "name": "comments-glossary-reach-dangling-footnote-no-notes", "sha256": "ee62b61a08118e9101de38d75191c518d374f2ca7682f9dd1f849a4288f80808", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00003__wfv__comments-glossary-reach-dangling-footnote-no-notes.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-glossary-reach-dangling-footnote-no-notes_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 2, "name": "comments-glossary-reach-dangling-footnote-no-notes", "sha256": "ee62b61a08118e9101de38d75191c518d374f2ca7682f9dd1f849a4288f80808", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00003__wfv__comments-glossary-reach-dangling-footnote-no-notes.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-glossary-reach-dangling-footnote-no-notes_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 1, "name": "comments-both-reaches-dangling-footnote-no-notes", "sha256": "72b98cefa6e9ac2856d4d1d4c760573570790073879d696140b74de0a854cee6", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00000__wfv__comments-both-reaches-dangling-footnote-no-notes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:15:19.256 'Word found unreadable content in 00000__wfv__comments-both-reaches-dangling-footnote-no-notes.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:15:19.809 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-both-reaches-dan...)\""]}
{"run": "s66a", "pass": 2, "name": "comments-both-reaches-dangling-footnote-no-notes", "sha256": "72b98cefa6e9ac2856d4d1d4c760573570790073879d696140b74de0a854cee6", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00000__wfv__comments-both-reaches-dangling-footnote-no-notes.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:18:29.090 'Word found unreadable content in 00000__wfv__comments-both-reaches-dangling-footnote-no-notes.... D … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:18:29.647 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-both-reaches-dan...)\""]}
{"run": "s66a", "pass": 1, "name": "endnotes-in-package-nested-dangling-footnote", "sha256": "b127fb1716b4207dca4affdbd2a91c82040ddbcb17ecc78debda567f1a9bb3e3", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00005__wfv__endnotes-in-package-nested-dangling-footnote.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-in-package-nested-dangling-footnote_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 2, "name": "endnotes-in-package-nested-dangling-footnote", "sha256": "b127fb1716b4207dca4affdbd2a91c82040ddbcb17ecc78debda567f1a9bb3e3", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00005__wfv__endnotes-in-package-nested-dangling-footnote.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-in-package-nested-dangling-footnote_byword.pdf (15783 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 1, "name": "s66a-control-minimal-end", "sha256": "27fbf3b06ebb5498f493ac924f7cf9843c8e6ff476b8d52a72c894b1d9c3acd9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:17:58+00:00", "staged": "00006__wfv__s66a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s66a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s66a", "pass": 2, "name": "s66a-control-minimal-end", "sha256": "27fbf3b06ebb5498f493ac924f7cf9843c8e6ff476b8d52a72c894b1d9c3acd9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:21:10+00:00", "staged": "00006__wfv__s66a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s66a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 66 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s66builder.mts`:

```ts
// Session 66 (2026-10-26): calibrations for session 65's surprises.
// s66a: s65d refused a comments part read by both the main document and a glossary (its comment holding a footnote
//       reference only the glossary's notes define), and opened the main-only reach clean. Is the shared reach itself
//       refused, and does Word judge a dangling footnote reference in a comments part at all? Also: s65a opened a
//       footnote reference inside footnotes and an endnote reference inside endnotes clean; a footnote reference inside
//       an endnotes part is the remaining cross-kind case.
// Every row records the validator revision it was judged at (`validatorRevision`). Helpers are copied from s65builder.mts.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s66a pnpm exec node --import tsx s66builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const WS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, extra = "") =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${extra}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

/** The minimal parts with `word/footer1.xml` read through the section's default footer reference, holding `run`. */
const withReadFooter = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r>${run}</w:p></w:ftr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
            [CT]: overrides(parts[CT]!, ["word/footer1.xml", `${WML}.footer+xml`]),
        },
        "",
        `<w:footerReference w:type="default" r:id="rIdF"/>`,
    );

/** Two footnotes relationships in document order: word/footnotes.xml holding `first`, then word/notes2.xml (footnotes+xml) holding `second`; the body references footnote 1. */
const twoFootnotes = (first: string, second: string) => {
    const parts = withNotes("footnote", first);
    return buildDocx(
        mainWith(
            {
                ...parts,
                "word/notes2.xml": notesXml("footnote", second),
                [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "footnotes", "notes2.xml")),
                [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.footnotes+xml`]),
            },
            noteRef("footnote", "1"),
        ),
    );
};

/** Session 46's Word-saved ISO Strict fixture (pinned clean-open), with `edit` applied to its main document. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (main: string) => string = (main) => main) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    parts[MAIN] = edit(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};

/** A used `word/comments.xml` whose stored root is mc:AlternateContent; its w14 Choice holds the w:comments root with comment 0. */
const rootAlternateComments = (type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml":
                    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">` +
                    `<w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** Comment 0 (own root) with its range start inside an mc:Choice requiring `requires` (empty Fallback), the end and the reference outside. */
const splitRange = (requires: string) =>
    buildDocx(
        mainWith(
            withComments(comment("0")),
            alternate(requires, `<w:commentRangeStart w:id="0"/>`, "") +
                `<w:r><w:t>ranged</w:t></w:r><w:commentRangeEnd w:id="0"/>` +
                commentRef("0"),
        ),
    );

/** The minimal package with a reached glossary whose own sidecar relates word/glossary/footnotes.xml holding footnote `held`. */
const glossaryWithFootnotes = (held: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${TEXT_P}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "footnotes", "footnotes.xml")}</Relationships>`,
    "word/glossary/footnotes.xml": notesXml("footnote", held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(
        P[CT]!,
        ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
        ["word/glossary/footnotes.xml", `${WML}.footnotes+xml`],
    ),
});
/** Footnote 1 stored at `stored`, typed `type`, named only by a footnotes relationship with `target` and `extra`; the body references footnote 1. */
const footnotesAt = (stored: string, type: string, target: string, extra = "") =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml("footnote", "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target, extra)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef("footnote", "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const FOOTNOTES = `${WML}.footnotes+xml`;
const STYLES = `${WML}.styles+xml`;
const COMMENTS = `${WML}.comments+xml`;
/** Note 1 of `kind` stored at `stored`, typed `type`, named only by a `<kind>s` relationship with `target`; the body references it. */
const notesAt = (kind: Kind, stored: string, type: string, target: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef(kind, "1"),
        ),
    );
/** Note 1 of `kind` stored at `stored` (its paragraph also holding `nested`), named only by a `<kind>s` relationship with `target`; the body references note 1. */
const notesWithNested = (kind: Kind, stored: string, target: string, nested: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="1"><w:p><w:r><w:t>Text</w:t></w:r>${nested}</w:p></w:${kind}></w:${kind}s>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, `${WML}.${kind}s+xml`]),
            },
            noteRef(kind, "1"),
        ),
    );
/** A used `word/comments.xml` stored as `stored` and typed `type`; the body references comment 0. */
const usedComments = (stored: string, type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml": stored,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** s63b's stored root (an mc:AlternateContent whose Choice holds the w:comments root) with `edit` applied: text before the root, a non-empty Fallback, text between the branches, another Requires, or a Strict root. */
const alternateCommentsRoot = ({ before = "", fallback = "", between = "", requires = "w14", rootNs = W } = {}) =>
    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"${requires === "w" ? ` xmlns:w="${W}"` : ""}><mc:Choice Requires="${requires}">` +
    `${before}<w:comments xmlns:w="${rootNs}">${comment("0")}</w:comments></mc:Choice>${between}` +
    (fallback ? `<mc:Fallback>${fallback}</mc:Fallback>` : "<mc:Fallback/>") +
    "</mc:AlternateContent>";
/** A reached glossary relating its own word/glossary/footnotes.xml (footnote 1), plus word/comments.xml whose comment 0 holds a footnote reference to 1, read by the main document, the glossary or both. */
const sharedComments = (main: boolean, glossary: boolean) => {
    const parts = glossaryWithFootnotes("1");
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Text</w:t></w:r>${noteRef("footnote", "1")}</w:p></w:comment></w:comments>`,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", COMMENTS]),
    };
    if (glossary) {
        next["word/glossary/document.xml"] = replaceOnce(
            next["word/glossary/document.xml"]!,
            "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
            `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${commentRef("0")}</w:p>`,
        );
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    }
    if (!main) return buildDocx(next);
    return buildDocx(
        mainWith({ ...next, [SIDECAR]: appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")) }, commentRef("0")),
    );
};

/** word/comments.xml whose comment 0 holds `inComment`, read by the main document and/or the glossary; `notes` adds the glossary's footnotes part (footnote 1). */
const commentsReach = (main: boolean, glossary: boolean, inComment: string, notes = true) => {
    const parts = notes ? glossaryWithFootnotes("1") : glossaryWithFootnotes("1");
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Text</w:t></w:r>${inComment}</w:p></w:comment></w:comments>`,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", COMMENTS]),
    };
    if (!notes) {
        delete next["word/glossary/footnotes.xml"];
        next["word/glossary/_rels/document.xml.rels"] = replaceOnce(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rId1", "footnotes", "footnotes.xml"),
            "",
        );
        next[CT] = replaceOnce(next[CT]!, `<Override PartName="/word/glossary/footnotes.xml" ContentType="${WML}.footnotes+xml"/>`, "");
    }
    if (glossary) {
        next["word/glossary/document.xml"] = replaceOnce(
            next["word/glossary/document.xml"]!,
            "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
            `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${commentRef("0")}</w:p>`,
        );
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    }
    if (!main) return buildDocx(next);
    return buildDocx(
        mainWith({ ...next, [SIDECAR]: appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")) }, commentRef("0")),
    );
};

const chunks: Record<string, Row[]> = {
    s66a: withControls("s66a", [
        [
            "comments-both-reaches-no-note-reference",
            "calibration for s65d: word/comments.xml read by both the main document and a reached glossary; comment 0 holds no note reference",
            () => commentsReach(true, true, "", false),
        ],
        [
            "comments-footnote-glossary-only-both-reaches-repeat",
            "repeat of s65d: the same shared comments part, comment 0 holding a footnote reference to 1 that only the glossary's notes part defines",
            () => sharedComments(true, true),
        ],
        [
            "comments-main-reach-dangling-footnote-no-notes",
            "word/comments.xml read by the main document only; comment 0 holds a footnote reference to 99; no part anywhere defines a footnote (the glossary has no notes part)",
            () => commentsReach(true, false, noteRef("footnote", "99"), false),
        ],
        [
            "comments-glossary-reach-dangling-footnote-no-notes",
            "the same comments part read by the glossary only; no part defines a footnote",
            () => commentsReach(false, true, noteRef("footnote", "99"), false),
        ],
        [
            "comments-both-reaches-dangling-footnote-no-notes",
            "the same comments part read by both; no part defines a footnote",
            () => commentsReach(true, true, noteRef("footnote", "99"), false),
        ],
        [
            "endnotes-in-package-nested-dangling-footnote",
            "word/endnotes.xml, related in-package: endnote 1 holds a footnote reference to 99 (no footnotes part); the body references endnote 1",
            () => notesWithNested("endnote", "word/endnotes.xml", "endnotes.xml", noteRef("footnote", "99")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
writeFileSync(path.join(dir, "..", "specimens.jsonl"), "");
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-66 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s66a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s66/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-66 parts of docs/plans/evidence/word-probes-2026-10-24.md into s66/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s66a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s66/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 66: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "Calibrations for session 65's surprises. One chunk, "
    "opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the "
    "manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    f"builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "- **A comments part both the main document and a glossary read (s66a).** With no note reference at all, a "
    "`word/comments.xml` that both the main document and a reached glossary relate and reference gets the recovery offer, so "
    "the shared reach, not the note reference, is what Word refused in s65d (that row, repeated, is refused again). Word-valid "
    "accepts the calibration: a false negative.",
    "- **Dangling footnote references in comments (s66a).** With no footnotes part anywhere, a comment holding a footnote "
    "reference to 99 opens clean when only the main document, or only the glossary, reads the comments part; read by both, it "
    "gets the recovery offer, as the shared reach does without the reference. Word-valid rejects all three: the two single-reach "
    "rows are false positives.",
    "- **A footnote reference inside an endnotes part (s66a).** Endnote 1 holding a footnote reference to 99, with no footnotes "
    "part, opens clean. With session 16's endnote reference inside footnotes and session 65's same-kind rows, every nesting of "
    "a note reference in a notes part that these sessions stored opens clean. Word-valid rejects this row: a false positive.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 66</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 66 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s66builder.mts", ROOT / "s66builder.mts", "ts"), ("compare.py", ROOT / "s66/compare.py", "python"),
                         ("section.py", ROOT / "s66/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s66/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 67: 23:33Z–23:39Z on 2026-10-26, validator columns at 1dd3500b

The scope of [#850](https://github.com/jandira-tech/docx-validate/issues/850) and [#851](https://github.com/jandira-tech/docx-validate/issues/851). Two chunks, each opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 20 of 20 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`1dd3500b331b8a0cafa774b9dc109242222c5b9f`).

- **Parts both story roots read (s67a, #850).** Session 66's shared comments part, related and referenced by both the main document and a reached glossary, is refused again. Related by both but referenced by only one of them, or by neither, it opens clean, so the refusal needs both roots to use the part. A `word/footnotes.xml` that the main document relates and the glossary relates as `../footnotes.xml`, each referencing footnote 1, is refused too, and so is its endnotes twin; referenced by the body only, the shared footnotes part opens clean. Word-valid accepts all seven rows: three false negatives.
- **Text directly inside `mc:AlternateContent` (s67b, #851).** In a used `word/comments.xml` typed comments whose stored root is s63b's AlternateContent, text before the Choice, text after the Fallback, text after a Choice with no Fallback, and text between two Choices (the second requiring a namespace Word does not understand) each get the recovery offer; the no-Fallback and two-Choice roots without the text open clean here, as s63b's root did in session 63, and so does a newline and spaces between the Choice and the Fallback. In the main document, a run-level AlternateContent with text between its Choice and its Fallback is refused, and without the text it opens clean. Word-valid accepts every row: five false negatives.

| Run    | Observed             | Specimen                                            | Shape                                                                                                                                                               | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 1dd3500b | strict at 1dd3500b                                                                                              |
| ------ | -------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------- |
| `s67a` | 23:33:50Z, 23:35:24Z | `s67a-control-minimal`                              | control                                                                                                                                                             | `d0e3c8b47eb4bdb8` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                           |
| `s67a` | 23:33:50Z, 23:35:24Z | `comments-both-reaches-repeat`                      | repeat of s66a: word/comments.xml related and referenced by both the main document and a reached glossary; comment 0 holds only text                                | `c388025ca85c5fdc` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`                    |
| `s67a` | 23:33:50Z, 23:35:24Z | `comments-both-relate-main-references`              | the same part related by both, referenced by the main document's body only                                                                                          | `f70bef8e6519a78c` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`                    |
| `s67a` | 23:33:50Z, 23:35:24Z | `comments-both-relate-glossary-references`          | the same part related by both, referenced by the glossary's docPart only                                                                                            | `713bc7fb5878ee4e` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`                    |
| `s67a` | 23:33:50Z, 23:35:24Z | `comments-both-relate-neither-references`           | the same part related by both, referenced by neither                                                                                                                | `881f03d3c1dbe8f7` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `paraid-missing-element`                    |
| `s67a` | 23:33:50Z, 23:35:24Z | `footnotes-shared-both-reaches`                     | word/footnotes.xml (footnote 1) related by the main document and by the glossary as ../footnotes.xml; the body and the glossary's docPart each reference footnote 1 | `abcc0fac2bc48f0e` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `paraid-missing-element`, `paraid-missing-element`                                                     |
| `s67a` | 23:33:50Z, 23:35:24Z | `footnotes-shared-main-references-calibration`      | calibration: the same part related by both, referenced by the body only                                                                                             | `446f2d43db247077` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element`, `paraid-missing-element`                                                     |
| `s67a` | 23:33:50Z, 23:35:24Z | `endnotes-shared-both-reaches`                      | the endnotes twin: word/endnotes.xml related by both, endnote 1 referenced by both                                                                                  | `2153feaf9deb0897` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `paraid-missing-element`, `paraid-missing-element`                                                     |
| `s67a` | 23:33:50Z, 23:35:24Z | `s67a-control-minimal-end`                          | control                                                                                                                                                             | `d0e3c8b47eb4bdb8` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                           |
| `s67b` | 23:38:57Z, 23:39:28Z | `s67b-control-minimal`                              | control                                                                                                                                                             | `27bcfc1a0e00a71f` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                           |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-text-before-choice`             | word/comments.xml (typed comments), stored root mc:AlternateContent: text, then s63b's w14 Choice holding the w:comments root, then an empty Fallback               | `4b781ead68700fef` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error` |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-text-after-fallback`            | the same root with the text after the empty Fallback                                                                                                                | `9346be853e174d0b` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error` |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-text-no-fallback`               | the w14 Choice holding the root, then text, and no Fallback                                                                                                         | `ff1e727e9ac92bc8` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error` |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-no-fallback-calibration`        | calibration: the w14 Choice holding the root and no Fallback; no text                                                                                               | `dec3ac4665f1cdb9` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`                             |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-whitespace-between-calibration` | calibration: a newline and spaces (whitespace only) between the Choice and the empty Fallback                                                                       | `fcb0add5c2f47995` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`                             |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-two-choices-calibration`        | calibration: the w14 Choice holding the root, a second Choice requiring an unknown namespace holding the root, then an empty Fallback; no text                      | `839b9d1a00532438` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`                             |
| `s67b` | 23:38:57Z, 23:39:28Z | `comments-alternate-text-between-choices`           | the same two Choices with text between them                                                                                                                         | `3d92ececc7c1eee0` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `comment-thread-count-mismatch`, `paraid-missing-element`, `mce-malformed`, `xsd-summary`, `xsd-error` |
| `s67b` | 23:38:57Z, 23:39:28Z | `body-alternate-text-between`                       | the main document's paragraph holds a run-level mc:AlternateContent: a w14 Choice run, text, then a Fallback run                                                    | `07f5bbe6fe6c0c4c` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `xsd-summary`, `xsd-error`                                                                             |
| `s67b` | 23:38:57Z, 23:39:28Z | `body-alternate-calibration`                        | calibration: the same run-level mc:AlternateContent without the text                                                                                                | `51032d34b23ccb5b` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                           |
| `s67b` | 23:38:57Z, 23:39:28Z | `s67b-control-minimal-end`                          | control                                                                                                                                                             | `dc98c013154c391a` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                           |

<details><summary>Raw records, session 67</summary>

```jsonl
{"run": "s67a", "pass": 1, "name": "s67a-control-minimal", "sha256": "d0e3c8b47eb4bdb8764342c094be54f9366e5fe92f9d32fe293bc0118e00273b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00008__wfv__s67a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "s67a-control-minimal", "sha256": "d0e3c8b47eb4bdb8764342c094be54f9366e5fe92f9d32fe293bc0118e00273b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00008__wfv__s67a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 1, "name": "comments-both-reaches-repeat", "sha256": "c388025ca85c5fdc6520a754470e8ced38bb7af654351582c5ec370a5249b2dd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00000__wfv__comments-both-reaches-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:32:38.957 'Word found unreadable content in 00000__wfv__comments-both-reaches-repeat.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:32:39.492 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-both-reaches-rep...)\""]}
{"run": "s67a", "pass": 2, "name": "comments-both-reaches-repeat", "sha256": "c388025ca85c5fdc6520a754470e8ced38bb7af654351582c5ec370a5249b2dd", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00000__wfv__comments-both-reaches-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:34:21.986 'Word found unreadable content in 00000__wfv__comments-both-reaches-repeat.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:34:22.526 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__comments-both-reaches-rep...)\""]}
{"run": "s67a", "pass": 1, "name": "comments-both-relate-main-references", "sha256": "f70bef8e6519a78ca63ef421218054701e37cd6123dfa4d9ee5472d9749e3a36", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00002__wfv__comments-both-relate-main-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-main-references_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "comments-both-relate-main-references", "sha256": "f70bef8e6519a78ca63ef421218054701e37cd6123dfa4d9ee5472d9749e3a36", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00002__wfv__comments-both-relate-main-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-main-references_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 1, "name": "comments-both-relate-glossary-references", "sha256": "713bc7fb5878ee4e33525c4b1d3b9b80f4257fa74d2e079a2a628c78c6d99f03", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00001__wfv__comments-both-relate-glossary-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-glossary-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "comments-both-relate-glossary-references", "sha256": "713bc7fb5878ee4e33525c4b1d3b9b80f4257fa74d2e079a2a628c78c6d99f03", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00001__wfv__comments-both-relate-glossary-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-glossary-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 1, "name": "comments-both-relate-neither-references", "sha256": "881f03d3c1dbe8f7b050a2a68d5af9bdc3469ee000627f5cab02d7b0cf40a96f", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00003__wfv__comments-both-relate-neither-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-neither-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "comments-both-relate-neither-references", "sha256": "881f03d3c1dbe8f7b050a2a68d5af9bdc3469ee000627f5cab02d7b0cf40a96f", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00003__wfv__comments-both-relate-neither-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-both-relate-neither-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 1, "name": "footnotes-shared-both-reaches", "sha256": "abcc0fac2bc48f0e5790d3c6e16027bd27e617adae51ace5d888ac9be45647e9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00005__wfv__footnotes-shared-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:33:48.915 Microsoft Word, Word found unreadable content in 00005__wfv__footnotes-shared-both-reaches.docx. Do  … t? If you trust the source of this document, click Yes.", "2026-10-26 19:33:49.566 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__footnotes-shared-both-rea...)\""]}
{"run": "s67a", "pass": 2, "name": "footnotes-shared-both-reaches", "sha256": "abcc0fac2bc48f0e5790d3c6e16027bd27e617adae51ace5d888ac9be45647e9", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00005__wfv__footnotes-shared-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:35:22.925 Microsoft Word, Word found unreadable content in 00005__wfv__footnotes-shared-both-reaches.docx. Do  … t? If you trust the source of this document, click Yes."]}
{"run": "s67a", "pass": 1, "name": "footnotes-shared-main-references-calibration", "sha256": "446f2d43db247077912fbd75dc5bf3f3b15bfa354c6be98a91eee0a3048a88b5", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00006__wfv__footnotes-shared-main-references-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-shared-main-references-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "footnotes-shared-main-references-calibration", "sha256": "446f2d43db247077912fbd75dc5bf3f3b15bfa354c6be98a91eee0a3048a88b5", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00006__wfv__footnotes-shared-main-references-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-shared-main-references-calibration_byword.pdf (15513 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 1, "name": "endnotes-shared-both-reaches", "sha256": "2153feaf9deb089731a2d054fb291ae5f6f6c2fde534515f2b89ce63b6de1682", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00004__wfv__endnotes-shared-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:32:56.924 \"Word found unreadable content in 00004__wfv__endnotes-shared-both-reaches.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\""]}
{"run": "s67a", "pass": 2, "name": "endnotes-shared-both-reaches", "sha256": "2153feaf9deb089731a2d054fb291ae5f6f6c2fde534515f2b89ce63b6de1682", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00004__wfv__endnotes-shared-both-reaches.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:34:39.141 \"Word found unreadable content in 00004__wfv__endnotes-shared-both-reaches.docx. Do you want to reco … ? If you trust the source of this document, click Yes.\""]}
{"run": "s67a", "pass": 1, "name": "s67a-control-minimal-end", "sha256": "d0e3c8b47eb4bdb8764342c094be54f9366e5fe92f9d32fe293bc0118e00273b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:33:50+00:00", "staged": "00007__wfv__s67a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67a", "pass": 2, "name": "s67a-control-minimal-end", "sha256": "d0e3c8b47eb4bdb8764342c094be54f9366e5fe92f9d32fe293bc0118e00273b", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:35:24+00:00", "staged": "00007__wfv__s67a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "s67b-control-minimal", "sha256": "27bcfc1a0e00a71fad306f76af8b24b425f775f431822be43718a37529120815", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00010__wfv__s67b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "s67b-control-minimal", "sha256": "27bcfc1a0e00a71fad306f76af8b24b425f775f431822be43718a37529120815", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00010__wfv__s67b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-text-before-choice", "sha256": "4b781ead68700fefca3f8ca5517472ffc9efc060d3acd9f3265067e477e48ad0", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00004__wfv__comments-alternate-text-before-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:36:49.256 Microsoft Word, Word found unreadable content in 00004__wfv__comments-alternate-text-before-choice.d … t? If you trust the source of this document, click Yes.", "2026-10-26 19:36:49.287 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__comments-alternate-text-b...)'"]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-text-before-choice", "sha256": "4b781ead68700fefca3f8ca5517472ffc9efc060d3acd9f3265067e477e48ad0", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00004__wfv__comments-alternate-text-before-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:39:17.735 'Word found unreadable content in 00004__wfv__comments-alternate-text-before-choice.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:39:18.520 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__comments-alternate-text-b...)\""]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-text-after-fallback", "sha256": "9346be853e174d0b2457c1bd7549e4da80b5eab24b871f983ee0303c15093d44", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00003__wfv__comments-alternate-text-after-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:36:05.130 \"Word found unreadable content in 00003__wfv__comments-alternate-text-after-fallback.docx. Do you wa … ? If you trust the source of this document, click Yes.\""]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-text-after-fallback", "sha256": "9346be853e174d0b2457c1bd7549e4da80b5eab24b871f983ee0303c15093d44", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00003__wfv__comments-alternate-text-after-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:39:13.570 'Word found unreadable content in 00003__wfv__comments-alternate-text-after-fallback.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:39:14.370 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__comments-alternate-text-a...)\""]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-text-no-fallback", "sha256": "ff1e727e9ac92bc80ccff58963dfd2efe867f61978278090496494688b87c2bb", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00006__wfv__comments-alternate-text-no-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:38:55.652 \"Word found unreadable content in 00006__wfv__comments-alternate-text-no-fallback.docx. Do you want  … ? If you trust the source of this document, click Yes.\"", "2026-10-26 19:38:55.656 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__comments-alternate-text-n...)\""]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-text-no-fallback", "sha256": "ff1e727e9ac92bc80ccff58963dfd2efe867f61978278090496494688b87c2bb", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00006__wfv__comments-alternate-text-no-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:39:26.055 'Word found unreadable content in 00006__wfv__comments-alternate-text-no-fallback.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:39:26.836 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__comments-alternate-text-n...)\""]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-no-fallback-calibration", "sha256": "dec3ac4665f1cdb9d8448cbc9975d2b8d561e0d3832b0ea79024dd9cd00e0c30", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00002__wfv__comments-alternate-no-fallback-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-no-fallback-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-no-fallback-calibration", "sha256": "dec3ac4665f1cdb9d8448cbc9975d2b8d561e0d3832b0ea79024dd9cd00e0c30", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00002__wfv__comments-alternate-no-fallback-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-no-fallback-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-whitespace-between-calibration", "sha256": "fcb0add5c2f4799567c90e7762738a1e06a7df8b78d2c1ff33bf930f3db1ea16", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00008__wfv__comments-alternate-whitespace-between-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-whitespace-between-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-whitespace-between-calibration", "sha256": "fcb0add5c2f4799567c90e7762738a1e06a7df8b78d2c1ff33bf930f3db1ea16", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00008__wfv__comments-alternate-whitespace-between-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-whitespace-between-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-two-choices-calibration", "sha256": "839b9d1a0053243886dc064a9edb833b1a779f39c47fad038ebde0e8326456bc", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00007__wfv__comments-alternate-two-choices-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-two-choices-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-two-choices-calibration", "sha256": "839b9d1a0053243886dc064a9edb833b1a779f39c47fad038ebde0e8326456bc", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00007__wfv__comments-alternate-two-choices-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-alternate-two-choices-calibration_byword.pdf (34583 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "comments-alternate-text-between-choices", "sha256": "3d92ececc7c1eee0a8f1299cb839972337218b5ab46be0c3f6d10f3e069f3e6e", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00005__wfv__comments-alternate-text-between-choices.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:38:50.404 'Word found unreadable content in 00005__wfv__comments-alternate-text-between-choices.docx. Do you w … ? If you trust the source of this document, click Yes.'"]}
{"run": "s67b", "pass": 2, "name": "comments-alternate-text-between-choices", "sha256": "3d92ececc7c1eee0a8f1299cb839972337218b5ab46be0c3f6d10f3e069f3e6e", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00005__wfv__comments-alternate-text-between-choices.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:39:21.920 'Word found unreadable content in 00005__wfv__comments-alternate-text-between-choices.docx. Do you w … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:39:22.725 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__comments-alternate-text-b...)\""]}
{"run": "s67b", "pass": 1, "name": "body-alternate-text-between", "sha256": "07f5bbe6fe6c0c4cba108e1963376df920d6193328e03ea057d0285ed67ba9f4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00001__wfv__body-alternate-text-between.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:35:48.495 \"Word found unreadable content in 00001__wfv__body-alternate-text-between.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""]}
{"run": "s67b", "pass": 2, "name": "body-alternate-text-between", "sha256": "07f5bbe6fe6c0c4cba108e1963376df920d6193328e03ea057d0285ed67ba9f4", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00001__wfv__body-alternate-text-between.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 19:39:09.239 'Word found unreadable content in 00001__wfv__body-alternate-text-between.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-26 19:39:10.015 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__body-alternate-text-betwe...)\""]}
{"run": "s67b", "pass": 1, "name": "body-alternate-calibration", "sha256": "51032d34b23ccb5bae56473d6f4759e165748a8ebf99e5bed7f204cd205f1409", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00000__wfv__body-alternate-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF body-alternate-calibration_byword.pdf (16007 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "body-alternate-calibration", "sha256": "51032d34b23ccb5bae56473d6f4759e165748a8ebf99e5bed7f204cd205f1409", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00000__wfv__body-alternate-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF body-alternate-calibration_byword.pdf (16007 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 1, "name": "s67b-control-minimal-end", "sha256": "dc98c013154c391afd0985e2f6d8fbe9ffe11927f110e5399c4547f322427e21", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:38:57+00:00", "staged": "00009__wfv__s67b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s67b", "pass": 2, "name": "s67b-control-minimal-end", "sha256": "dc98c013154c391afd0985e2f6d8fbe9ffe11927f110e5399c4547f322427e21", "validatorRevision": "1dd3500b331b8a0cafa774b9dc109242222c5b9f", "observedAt": "2026-10-26T23:39:28+00:00", "staged": "00009__wfv__s67b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s67b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 67 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s67builder.mts`:

```ts
// Session 67 (2026-10-26): the scope of #850 and #851.
// s67a (#850): session 66 refused word/comments.xml read by both the main document and a reached glossary. Which half
//       matters (both relating it, or both referencing it), and are shared footnotes and endnotes parts refused too?
// s67b (#851): session 65 refused text directly inside a comments part's root mc:AlternateContent, between its Choice
//       and its Fallback, and opened text inside the Choice or the Fallback clean. Are the other positions refused,
//       is whitespace there clean, and is the same shape in a body run refused?
// Every row records the validator revision it was judged at (`validatorRevision`). Helpers are copied from s66builder.mts.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root as a copy: BUILD_DIR=<chunk>/src CHUNK=s67a pnpm exec node --import tsx s67builder.tmp.mts
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import JSZip from "jszip";
import { MINIMAL_PARTS, buildDocx } from "./tests/support/minimal-docx";
import { validate } from "./src/scripts/office/validate";

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
const WS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
const U = "urn:example:unknown";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Text</w:t></w:r></w:p>";
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string, extra = "") =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"${extra}/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const control = () => buildDocx({ ...P });

/**
 * `parts` with the main document's `r:` and `u:` prefixes declared (`u` is bound to a namespace Word does not
 * understand and appears only in `Requires`), `sect` first in its `w:sectPr` and `run` appended inside its only paragraph.
 */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(
            replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}" xmlns:u="${U}"`),
            "<w:sectPr>",
            `<w:sectPr>${sect}`,
        ),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` with the main document stored as `word/<name>`: the part, its sidecar, the officeDocument target and its Override. */
const renameMain = (parts: Record<string, string>, name: string): Record<string, string> => {
    const next: Record<string, string> = { ...parts, [`word/${name}`]: parts[MAIN]!, [`word/_rels/${name}.rels`]: parts[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(parts["_rels/.rels"]!, 'Target="word/document.xml"', `Target="word/${name}"`);
    next[CT] = replaceOnce(parts[CT]!, 'PartName="/word/document.xml"', `PartName="/word/${name}"`);
    return next;
};

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` holding note `held`, related by the main document and typed by `type`. */
const withNotes = (kind: Kind, held: string, type = `${WML}.${kind}s+xml`): Record<string, string> => ({
    ...P,
    [`word/${kind}s.xml`]: notesXml(kind, held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`)),
    [CT]: overrides(P[CT]!, [`word/${kind}s.xml`, type]),
});

const comment = (id: string) => `<w:comment w:id="${id}" w:author="a">${TEXT_P}</w:comment>`;
const commentsRoot = (body: string) =>
    `${XML_DECL}<w:comments xmlns:w="${W}" xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${body}</w:comments>`;
/** The minimal parts with `word/comments.xml` holding `body`, related by the main document and typed by `type`. */
const withComments = (body: string, type = `${WML}.comments+xml`): Record<string, string> => ({
    ...P,
    "word/comments.xml": commentsRoot(body),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
    [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
});
const commentRef = (id: string) => `<w:r><w:commentReference w:id="${id}"/></w:r>`;
const alternate = (requires: string, choice: string, fallback: string) =>
    `<mc:AlternateContent><mc:Choice Requires="${requires}">${choice}</mc:Choice><mc:Fallback>${fallback}</mc:Fallback></mc:AlternateContent>`;

/** A read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header</w:t></w:r>${run}</w:p></w:hdr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(parts[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );

/** Two endnotes relationships in document order: word/endnotes.xml holding `first`, then word/notes2.xml (endnotes+xml) holding `second`. */
const twoEndnotes = (first: string, second: string, referenced: boolean) => {
    const parts = withNotes("endnote", first);
    const both = {
        ...parts,
        "word/notes2.xml": notesXml("endnote", second),
        [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "endnotes", "notes2.xml")),
        [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.endnotes+xml`]),
    };
    return buildDocx(referenced ? mainWith(both, noteRef("endnote", "1")) : both);
};

/** The minimal parts with `word/footer1.xml` read through the section's default footer reference, holding `run`. */
const withReadFooter = (parts: Record<string, string>, run: string): Record<string, string> =>
    mainWith(
        {
            ...parts,
            "word/footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer</w:t></w:r>${run}</w:p></w:ftr>`,
            [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
            [CT]: overrides(parts[CT]!, ["word/footer1.xml", `${WML}.footer+xml`]),
        },
        "",
        `<w:footerReference w:type="default" r:id="rIdF"/>`,
    );

/** Two footnotes relationships in document order: word/footnotes.xml holding `first`, then word/notes2.xml (footnotes+xml) holding `second`; the body references footnote 1. */
const twoFootnotes = (first: string, second: string) => {
    const parts = withNotes("footnote", first);
    return buildDocx(
        mainWith(
            {
                ...parts,
                "word/notes2.xml": notesXml("footnote", second),
                [SIDECAR]: appendRels(parts[SIDECAR]!, relationship("rIdN2", "footnotes", "notes2.xml")),
                [CT]: overrides(parts[CT]!, ["word/notes2.xml", `${WML}.footnotes+xml`]),
            },
            noteRef("footnote", "1"),
        ),
    );
};

/** Session 46's Word-saved ISO Strict fixture (pinned clean-open), with `edit` applied to its main document. */
const STRICT01 = "tests/fixtures/working/word-clean-strict01.docx";
const strict01 = async (edit: (main: string) => string = (main) => main) => {
    const zip = await JSZip.loadAsync(readFileSync(STRICT01));
    const parts: Record<string, string | Uint8Array> = {};
    for (const [name, entry] of Object.entries(zip.files)) if (!entry.dir) parts[name] = await entry.async("uint8array");
    parts[MAIN] = edit(Buffer.from(parts[MAIN] as Uint8Array).toString("utf8"));
    return buildDocx(parts);
};

/** A used `word/comments.xml` whose stored root is mc:AlternateContent; its w14 Choice holds the w:comments root with comment 0. */
const rootAlternateComments = (type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml":
                    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"><mc:Choice Requires="w14">` +
                    `<w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice><mc:Fallback/></mc:AlternateContent>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** Comment 0 (own root) with its range start inside an mc:Choice requiring `requires` (empty Fallback), the end and the reference outside. */
const splitRange = (requires: string) =>
    buildDocx(
        mainWith(
            withComments(comment("0")),
            alternate(requires, `<w:commentRangeStart w:id="0"/>`, "") +
                `<w:r><w:t>ranged</w:t></w:r><w:commentRangeEnd w:id="0"/>` +
                commentRef("0"),
        ),
    );

/** The minimal package with a reached glossary whose own sidecar relates word/glossary/footnotes.xml holding footnote `held`. */
const glossaryWithFootnotes = (held: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml":
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
        `<w:docPartBody>${TEXT_P}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`,
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "footnotes", "footnotes.xml")}</Relationships>`,
    "word/glossary/footnotes.xml": notesXml("footnote", held),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
    [CT]: overrides(
        P[CT]!,
        ["word/glossary/document.xml", `${WML}.document.glossary+xml`],
        ["word/glossary/footnotes.xml", `${WML}.footnotes+xml`],
    ),
});
/** Footnote 1 stored at `stored`, typed `type`, named only by a footnotes relationship with `target` and `extra`; the body references footnote 1. */
const footnotesAt = (stored: string, type: string, target: string, extra = "") =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml("footnote", "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target, extra)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef("footnote", "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];
const FOOTNOTES = `${WML}.footnotes+xml`;
const STYLES = `${WML}.styles+xml`;
const COMMENTS = `${WML}.comments+xml`;
/** Note 1 of `kind` stored at `stored`, typed `type`, named only by a `<kind>s` relationship with `target`; the body references it. */
const notesAt = (kind: Kind, stored: string, type: string, target: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, type]),
            },
            noteRef(kind, "1"),
        ),
    );
/** Note 1 of `kind` stored at `stored` (its paragraph also holding `nested`), named only by a `<kind>s` relationship with `target`; the body references note 1. */
const notesWithNested = (kind: Kind, stored: string, target: string, nested: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="1"><w:p><w:r><w:t>Text</w:t></w:r>${nested}</w:p></w:${kind}></w:${kind}s>`,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, `${WML}.${kind}s+xml`]),
            },
            noteRef(kind, "1"),
        ),
    );
/** A used `word/comments.xml` stored as `stored` and typed `type`; the body references comment 0. */
const usedComments = (stored: string, type: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                "word/comments.xml": stored,
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")),
                [CT]: overrides(P[CT]!, ["word/comments.xml", type]),
            },
            commentRef("0"),
        ),
    );
/** s63b's stored root (an mc:AlternateContent whose Choice holds the w:comments root) with `edit` applied: text before the root, a non-empty Fallback, text between the branches, another Requires, or a Strict root. */
const alternateCommentsRoot = ({ before = "", fallback = "", between = "", requires = "w14", rootNs = W } = {}) =>
    `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}"${requires === "w" ? ` xmlns:w="${W}"` : ""}><mc:Choice Requires="${requires}">` +
    `${before}<w:comments xmlns:w="${rootNs}">${comment("0")}</w:comments></mc:Choice>${between}` +
    (fallback ? `<mc:Fallback>${fallback}</mc:Fallback>` : "<mc:Fallback/>") +
    "</mc:AlternateContent>";
/** A reached glossary relating its own word/glossary/footnotes.xml (footnote 1), plus word/comments.xml whose comment 0 holds a footnote reference to 1, read by the main document, the glossary or both. */
const sharedComments = (main: boolean, glossary: boolean) => {
    const parts = glossaryWithFootnotes("1");
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Text</w:t></w:r>${noteRef("footnote", "1")}</w:p></w:comment></w:comments>`,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", COMMENTS]),
    };
    if (glossary) {
        next["word/glossary/document.xml"] = replaceOnce(
            next["word/glossary/document.xml"]!,
            "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
            `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${commentRef("0")}</w:p>`,
        );
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    }
    if (!main) return buildDocx(next);
    return buildDocx(
        mainWith({ ...next, [SIDECAR]: appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")) }, commentRef("0")),
    );
};

/** word/comments.xml whose comment 0 holds `inComment`, read by the main document and/or the glossary; `notes` adds the glossary's footnotes part (footnote 1). */
const commentsReach = (main: boolean, glossary: boolean, inComment: string, notes = true) => {
    const parts = notes ? glossaryWithFootnotes("1") : glossaryWithFootnotes("1");
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Text</w:t></w:r>${inComment}</w:p></w:comment></w:comments>`,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", COMMENTS]),
    };
    if (!notes) {
        delete next["word/glossary/footnotes.xml"];
        next["word/glossary/_rels/document.xml.rels"] = replaceOnce(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rId1", "footnotes", "footnotes.xml"),
            "",
        );
        next[CT] = replaceOnce(next[CT]!, `<Override PartName="/word/glossary/footnotes.xml" ContentType="${WML}.footnotes+xml"/>`, "");
    }
    if (glossary) {
        next["word/glossary/document.xml"] = replaceOnce(
            next["word/glossary/document.xml"]!,
            "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
            `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${commentRef("0")}</w:p>`,
        );
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    }
    if (!main) return buildDocx(next);
    return buildDocx(
        mainWith({ ...next, [SIDECAR]: appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml")) }, commentRef("0")),
    );
};

/** The minimal package with a reached glossary whose docPart body holds `gloss` in its paragraph; the glossary relates no notes part. */
const glossaryBare = (gloss = ""): Record<string, string> => {
    const parts = glossaryWithFootnotes("1");
    const next: Record<string, string> = { ...parts };
    delete next["word/glossary/footnotes.xml"];
    next["word/glossary/_rels/document.xml.rels"] = replaceOnce(
        next["word/glossary/_rels/document.xml.rels"]!,
        relationship("rId1", "footnotes", "footnotes.xml"),
        "",
    );
    next[CT] = replaceOnce(next[CT]!, `<Override PartName="/word/glossary/footnotes.xml" ContentType="${WML}.footnotes+xml"/>`, "");
    next["word/glossary/document.xml"] = replaceOnce(
        next["word/glossary/document.xml"]!,
        "<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r></w:p>",
        `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${gloss}</w:p>`,
    );
    return next;
};
/** word/comments.xml (comment 0, typed comments) related and referenced by the main document and the glossary as the flags say. */
const commentsShared = (mainRel: boolean, mainRef: boolean, glossRel: boolean, glossRef: boolean) => {
    const next = glossaryBare(glossRef ? commentRef("0") : "");
    next["word/comments.xml"] = commentsRoot(comment("0"));
    next[CT] = overrides(next[CT]!, ["word/comments.xml", COMMENTS]);
    if (glossRel)
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdC", "comments", "../comments.xml"),
        );
    if (mainRel) next[SIDECAR] = appendRels(next[SIDECAR]!, relationship("rIdC", "comments", "comments.xml"));
    return buildDocx(mainRef ? mainWith(next, commentRef("0")) : next);
};
/** word/<kind>s.xml (note 1) related by the main document and/or the glossary (as ../<kind>s.xml), each referencing note 1 when its flag says. */
const notesShared = (kind: Kind, mainRef: boolean, glossRel: boolean, glossRef: boolean) => {
    const next = glossaryBare(glossRef ? noteRef(kind, "1") : "");
    next[`word/${kind}s.xml`] = notesXml(kind, "1");
    next[CT] = overrides(next[CT]!, [`word/${kind}s.xml`, `${WML}.${kind}s+xml`]);
    next[SIDECAR] = appendRels(next[SIDECAR]!, relationship("rIdN", `${kind}s`, `${kind}s.xml`));
    if (glossRel)
        next["word/glossary/_rels/document.xml.rels"] = appendRels(
            next["word/glossary/_rels/document.xml.rels"]!,
            relationship("rIdN", `${kind}s`, `../${kind}s.xml`),
        );
    return buildDocx(mainRef ? mainWith(next, noteRef(kind, "1")) : next);
};
/** A used word/comments.xml (typed comments) whose stored root is mc:AlternateContent with `inner` as its content (Choice and Fallback markup with any text). */
const rootAlternate = (inner: string) =>
    usedComments(
        `${XML_DECL}<mc:AlternateContent xmlns:mc="${MC}" xmlns:w14="${W14}" xmlns:u="${U}">${inner}</mc:AlternateContent>`,
        COMMENTS,
    );
const CHOICE = `<mc:Choice Requires="w14"><w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice>`;
const UNKNOWN_CHOICE = `<mc:Choice Requires="u"><w:comments xmlns:w="${W}">${comment("0")}</w:comments></mc:Choice>`;
/** The main document (which declares mc and w14 already) with a run-level mc:AlternateContent in its paragraph: a w14 Choice run, `between`, then a Fallback run. */
const bodyAlternate = (between: string) =>
    buildDocx({
        ...P,
        [MAIN]: replaceOnce(
            P[MAIN]!,
            "</w:r></w:p>",
            `</w:r><mc:AlternateContent><mc:Choice Requires="w14"><w:r><w:t>Chosen</w:t></w:r></mc:Choice>${between}<mc:Fallback><w:r><w:t>Fallback</w:t></w:r></mc:Fallback></mc:AlternateContent></w:p>`,
        ),
    });

const chunks: Record<string, Row[]> = {
    s67a: withControls("s67a", [
        [
            "comments-both-reaches-repeat",
            "repeat of s66a: word/comments.xml related and referenced by both the main document and a reached glossary; comment 0 holds only text",
            () => commentsShared(true, true, true, true),
        ],
        [
            "comments-both-relate-main-references",
            "the same part related by both, referenced by the main document's body only",
            () => commentsShared(true, true, true, false),
        ],
        [
            "comments-both-relate-glossary-references",
            "the same part related by both, referenced by the glossary's docPart only",
            () => commentsShared(true, false, true, true),
        ],
        [
            "comments-both-relate-neither-references",
            "the same part related by both, referenced by neither",
            () => commentsShared(true, false, true, false),
        ],
        [
            "footnotes-shared-both-reaches",
            "word/footnotes.xml (footnote 1) related by the main document and by the glossary as ../footnotes.xml; the body and the glossary's docPart each reference footnote 1",
            () => notesShared("footnote", true, true, true),
        ],
        [
            "footnotes-shared-main-references-calibration",
            "calibration: the same part related by both, referenced by the body only",
            () => notesShared("footnote", true, true, false),
        ],
        [
            "endnotes-shared-both-reaches",
            "the endnotes twin: word/endnotes.xml related by both, endnote 1 referenced by both",
            () => notesShared("endnote", true, true, true),
        ],
    ]),
    s67b: withControls("s67b", [
        [
            "comments-alternate-text-before-choice",
            "word/comments.xml (typed comments), stored root mc:AlternateContent: text, then s63b's w14 Choice holding the w:comments root, then an empty Fallback",
            () => rootAlternate(`Stray${CHOICE}<mc:Fallback/>`),
        ],
        [
            "comments-alternate-text-after-fallback",
            "the same root with the text after the empty Fallback",
            () => rootAlternate(`${CHOICE}<mc:Fallback/>Stray`),
        ],
        [
            "comments-alternate-text-no-fallback",
            "the w14 Choice holding the root, then text, and no Fallback",
            () => rootAlternate(`${CHOICE}Stray`),
        ],
        [
            "comments-alternate-no-fallback-calibration",
            "calibration: the w14 Choice holding the root and no Fallback; no text",
            () => rootAlternate(CHOICE),
        ],
        [
            "comments-alternate-whitespace-between-calibration",
            "calibration: a newline and spaces (whitespace only) between the Choice and the empty Fallback",
            () => rootAlternate(`${CHOICE}\n  <mc:Fallback/>`),
        ],
        [
            "comments-alternate-two-choices-calibration",
            "calibration: the w14 Choice holding the root, a second Choice requiring an unknown namespace holding the root, then an empty Fallback; no text",
            () => rootAlternate(`${CHOICE}${UNKNOWN_CHOICE}<mc:Fallback/>`),
        ],
        [
            "comments-alternate-text-between-choices",
            "the same two Choices with text between them",
            () => rootAlternate(`${CHOICE}Stray${UNKNOWN_CHOICE}<mc:Fallback/>`),
        ],
        [
            "body-alternate-text-between",
            "the main document's paragraph holds a run-level mc:AlternateContent: a w14 Choice run, text, then a Fallback run",
            () => bodyAlternate("Stray"),
        ],
        ["body-alternate-calibration", "calibration: the same run-level mc:AlternateContent without the text", () => bodyAlternate("")],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = process.env.BUILD_DIR;
if (!dir) throw new Error("BUILD_DIR is required");
mkdirSync(dir, { recursive: true });
writeFileSync(path.join(dir, "..", "specimens.jsonl"), "");
for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const verdict = async (profile: "word-valid" | "strict") => {
        try {
            const r = await validate(path.join(dir, file), { profile });
            return {
                valid: r.valid,
                errors: [...new Set(r.issues.filter((x) => x.severity === "error").map((x) => `${x.code}@${x.path ?? "-"}`))],
            };
        } catch (error) {
            return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
        }
    };
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict("word-valid"),
        strict: await verdict("strict"),
    };
    appendFileSync(path.join(dir, "..", "specimens.jsonl"), JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-66 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s67a", "s67b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": "control-minimal" in spec["name"],
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s67/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-67 parts of docs/plans/evidence/word-probes-2026-10-24.md into s67/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s67a", "s67b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s67/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"
out = [
    f"### Session 67: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on 2026-10-26, validator columns at {at}",
    "",
    "The scope of [#850](https://github.com/jandira-tech/docx-validate/issues/850) and [#851](https://github.com/jandira-tech/docx-validate/issues/851). Two chunks, each "
    "opening and closing with the minimal control. Each ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the "
    "manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the "
    f"builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "- **Parts both story roots read (s67a, #850).** Session 66's shared comments part, related and referenced by both the "
    "main document and a reached glossary, is refused again. Related by both but referenced by only one of them, or by neither, "
    "it opens clean, so the refusal needs both roots to use the part. A `word/footnotes.xml` that the main document relates "
    "and the glossary relates as `../footnotes.xml`, each referencing footnote 1, is refused too, and so is its endnotes twin; "
    "referenced by the body only, the shared footnotes part opens clean. Word-valid accepts all seven rows: three false "
    "negatives.",
    "- **Text directly inside `mc:AlternateContent` (s67b, #851).** In a used `word/comments.xml` typed comments whose stored "
    "root is s63b's AlternateContent, text before the Choice, text after the Fallback, text after a Choice with no Fallback, "
    "and text between two Choices (the second requiring a namespace Word does not understand) each get the recovery offer; "
    "the no-Fallback and two-Choice roots without the text open clean here, as s63b's root did in session 63, and so does a "
    "newline and spaces between the Choice and the Fallback. In the main "
    "document, a run-level AlternateContent with text between its Choice and its Fallback is refused, and without the text "
    "it opens clean. Word-valid accepts every row: five false negatives.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 67</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 67 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s67builder.mts", ROOT / "s67builder.mts", "ts"), ("compare.py", ROOT / "s67/compare.py", "python"),
                         ("section.py", ROOT / "s67/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s67/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 68: 01:46Z–01:48Z on 2026-10-27, validator columns at f4cd929e

A two-run repeat of session 39 ([#661](https://github.com/jandira-tech/docx-validate/issues/661), [#662](https://github.com/jandira-tech/docx-validate/issues/662)). Session 39 ran each chunk once, before the two-runs-with-logs rule, and its controls were queued last in every chunk ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). Here each chunk holds session 39's six specimens, copied byte for byte (the builder checks every SHA-256 against session 39's row), and its minimal control twice, named so the driver's name-ordered queue opens one copy first and the other last; every run's manifest shows the controls opened 1st and 8th of 8. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 24 of 24 rows agree. The two times in Observed are the ends of the first and second runs. Shape repeats session 39's description. The builder recorded the validator revision in every row (`f4cd929e9a4075e110eed09dbe70703cd94ed792`).

- **Chart sources (s68a, #661).** The six unreferenced chart shapes, clean in session 39, open clean in both runs: a chart related from a referenced header's sidecar, from a reached glossary's footnotes part's sidecar and from the glossary document's sidecar, a chart whose only drawing sits in an unselected Fallback, a chart related twice and named by neither, and a chart related through an equivalent target spelling.
- **Package-root wrappers (s68b, #662).** The six compound `_rels/.rels` root wrappers, clean in session 39, open clean in both runs.
- **Referenced chart twins (s68c, #661).** Each of the six referenced twins gets the recovery offer in both runs, as in session 39.

Session 39's verdicts stand, now from two runs whose controls bracket the specimens. Word-valid matches Word on all 24 rows.

| Run    | Observed             | Specimen                                       | Shape                                                                                                         | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f4cd929e          | strict at f4cd929e                                                                  |
| ------ | -------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------- | ----------------------------------------------------------------------------------- |
| `s68a` | 01:46:57Z, 01:47:15Z | `00-s68a-control-first`                        | control                                                                                                       | `c6ed84a2f2856d73` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-header-unreferenced`                    | repeat of s39a: #661: chart related from a referenced header's sidecar, Id unused                             | `7d5241c17d9a533d` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`, `paraid-missing-element`                           |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-footnote-unreferenced`                  | repeat of s39a: #661: chart related from a reached glossary's footnotes sidecar, Id unused                    | `e7662793551bdd66` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `paraid-missing-element` |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-glossary-unreferenced`                  | repeat of s39a: #661: chart related from a reached glossary document's sidecar, Id unused                     | `b618ee1dc9c9fb8e` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `paraid-missing-element` |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-unselected-fallback`                    | repeat of s39a: #661: the drawing only in an unselected mc:Fallback (selected empty w14 Choice)               | `882d8c7da99a34eb` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`                                                     |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-two-relationships-no-references`        | repeat of s39a: #661: two chart relationships to one part, neither Id used                                    | `6284ceba197625d0` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                         |
| `s68a` | 01:46:57Z, 01:47:15Z | `chart-equivalent-target-unreferenced`         | repeat of s39a: #661: relationship targets CHARTS/%63hart1.xml, Id unused                                     | `1c081590957bc651` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `rels-missing-sidecar`, `xsd-summary`, `xsd-error`                         |
| `s68a` | 01:46:57Z, 01:47:15Z | `zz-s68a-control-last`                         | control                                                                                                       | `c6ed84a2f2856d73` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |
| `s68b` | 01:47:21Z, 01:47:28Z | `00-s68b-control-first`                        | control                                                                                                       | `3159271c0d644744` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-nested-fallback`                 | repeat of s39b: #662: Fallback holds a second wrapper whose Fallback holds Relationships                      | `9ccf796a2033f3fb` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-three-nested-fallback`           | repeat of s39b: #662: three nested Fallback wrappers                                                          | `f5f7164064cad9c4` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-multiple-choices`                | repeat of s39b: #662: unselected foo Choice, then a selected w14 Choice holding Relationships                 | `f04688ea800e34d4` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-first-of-two-understood-choices` | repeat of s39b: #662: two w14 Choices, the first holding Relationships, the second a foreign element          | `c1e962189097235f` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-mustunderstand-w14`              | repeat of s39b: #662: the Fallback wrapper with mc:MustUnderstand="w14"                                       | `5b068fd4eb0f6336` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `package-root-ignorable-child`                 | repeat of s39b: #662: the Fallback wrapper around a Relationships with mc:Ignorable="foo" and a foo:bad child | `2b8696a9abe9c303` | clean-open     | clean-open     | clean-open                 | valid                           | invalid: `xsd-summary`, `xsd-error`                                                 |
| `s68b` | 01:47:21Z, 01:47:28Z | `zz-s68b-control-last`                         | control                                                                                                       | `3159271c0d644744` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |
| `s68c` | 01:48:04Z, 01:48:58Z | `00-s68c-control-first`                        | control                                                                                                       | `9f7a3eb4f36859a7` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-header-referenced`                      | repeat of s39c: #661 twin: the header's drawing names the chart                                               | `9295270440c6ce2a` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `paraid-missing-element`                           |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-footnote-referenced`                    | repeat of s39c: #661 twin: the glossary footnotes' drawing names the chart                                    | `e6726a3858dad562` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `paraid-missing-element` |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-glossary-referenced`                    | repeat of s39c: #661 twin: the glossary document's drawing names the chart                                    | `68529f0b0e785513` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`, `paraid-missing-element`, `paraid-missing-element` |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-selected-fallback`                      | repeat of s39c: #661 twin: the drawing in a selected mc:Fallback (unselected foo Choice)                      | `4151aa20fc393248` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                     |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-two-relationships-one-reference`        | repeat of s39c: #661 twin: two chart relationships, the drawing names rId9                                    | `38692fa07ce8d1fc` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                     |
| `s68c` | 01:48:04Z, 01:48:58Z | `chart-equivalent-target-referenced`           | repeat of s39c: #661 twin: equivalent target, the drawing names it                                            | `a56b728ca9a3ab7b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-missing-sidecar` | invalid: `rels-missing-sidecar`                                                     |
| `s68c` | 01:48:04Z, 01:48:58Z | `zz-s68c-control-last`                         | control                                                                                                       | `9f7a3eb4f36859a7` | clean-open     | clean-open     | clean-open                 | valid                           | valid                                                                               |

<details><summary>Raw records, session 68</summary>

```jsonl
{"run": "s68a", "pass": 1, "name": "00-s68a-control-first", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00000__wfv__00-s68a-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68a-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "00-s68a-control-first", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00000__wfv__00-s68a-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68a-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-header-unreferenced", "sha256": "7d5241c17d9a533d31a0fda0375b529f889d2e329ecea72bce3b32d67384ab2c", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00004__wfv__chart-header-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-header-unreferenced_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-header-unreferenced", "sha256": "7d5241c17d9a533d31a0fda0375b529f889d2e329ecea72bce3b32d67384ab2c", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00004__wfv__chart-header-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-header-unreferenced_byword.pdf (15327 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-footnote-unreferenced", "sha256": "e7662793551bdd668fc097938c4cf34713dbed4449f129fd373da9d95239fb6e", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00002__wfv__chart-footnote-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-footnote-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-footnote-unreferenced", "sha256": "e7662793551bdd668fc097938c4cf34713dbed4449f129fd373da9d95239fb6e", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00002__wfv__chart-footnote-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-footnote-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-glossary-unreferenced", "sha256": "b618ee1dc9c9fb8e60fcf165c1d57b3ba35215a404e00b6127a412a81c07c8de", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00003__wfv__chart-glossary-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-glossary-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-glossary-unreferenced", "sha256": "b618ee1dc9c9fb8e60fcf165c1d57b3ba35215a404e00b6127a412a81c07c8de", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00003__wfv__chart-glossary-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-glossary-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-unselected-fallback", "sha256": "882d8c7da99a34eba8e901989d8b417c4734810cb8660177842d1e92d5f56bbc", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00006__wfv__chart-unselected-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-unselected-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-unselected-fallback", "sha256": "882d8c7da99a34eba8e901989d8b417c4734810cb8660177842d1e92d5f56bbc", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00006__wfv__chart-unselected-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-unselected-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-two-relationships-no-references", "sha256": "6284ceba197625d09663a2247a5e19fd3cc15052dec7b3ef97001b516cd2b2c8", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00005__wfv__chart-two-relationships-no-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-two-relationships-no-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-two-relationships-no-references", "sha256": "6284ceba197625d09663a2247a5e19fd3cc15052dec7b3ef97001b516cd2b2c8", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00005__wfv__chart-two-relationships-no-references.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-two-relationships-no-references_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "chart-equivalent-target-unreferenced", "sha256": "1c081590957bc65116e942e2667f0b5aa46b1d1beae96d47360327fabc6077ab", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00001__wfv__chart-equivalent-target-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-equivalent-target-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "chart-equivalent-target-unreferenced", "sha256": "1c081590957bc65116e942e2667f0b5aa46b1d1beae96d47360327fabc6077ab", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00001__wfv__chart-equivalent-target-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF chart-equivalent-target-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 1, "name": "zz-s68a-control-last", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:46:57+00:00", "staged": "00007__wfv__zz-s68a-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68a-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68a", "pass": 2, "name": "zz-s68a-control-last", "sha256": "c6ed84a2f2856d7308bce7899d502a7be65525743be85e9e451a3a1e4ddbecc7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:15+00:00", "staged": "00007__wfv__zz-s68a-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68a-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "00-s68b-control-first", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00000__wfv__00-s68b-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68b-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "00-s68b-control-first", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00000__wfv__00-s68b-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68b-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-nested-fallback", "sha256": "9ccf796a2033f3fbda906327851e7cc1d7740646a3f177305f4f48886a424432", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00005__wfv__package-root-nested-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-nested-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-nested-fallback", "sha256": "9ccf796a2033f3fbda906327851e7cc1d7740646a3f177305f4f48886a424432", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00005__wfv__package-root-nested-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-nested-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-three-nested-fallback", "sha256": "f5f7164064cad9c488545e4d5b47dcf96d6c199d463004f43945496479319860", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00006__wfv__package-root-three-nested-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-three-nested-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-three-nested-fallback", "sha256": "f5f7164064cad9c488545e4d5b47dcf96d6c199d463004f43945496479319860", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00006__wfv__package-root-three-nested-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-three-nested-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-multiple-choices", "sha256": "f04688ea800e34d49f20589b4f577dc8c3225bfb577485f32a3e329b499d9892", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00003__wfv__package-root-multiple-choices.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-multiple-choices_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-multiple-choices", "sha256": "f04688ea800e34d49f20589b4f577dc8c3225bfb577485f32a3e329b499d9892", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00003__wfv__package-root-multiple-choices.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-multiple-choices_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-first-of-two-understood-choices", "sha256": "c1e962189097235f640801e6fd9f9a485ac7b3953dc0b3a581d2606b3c06dfb0", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00001__wfv__package-root-first-of-two-understood-choices.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-first-of-two-understood-choices_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-first-of-two-understood-choices", "sha256": "c1e962189097235f640801e6fd9f9a485ac7b3953dc0b3a581d2606b3c06dfb0", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00001__wfv__package-root-first-of-two-understood-choices.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-first-of-two-understood-choices_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-mustunderstand-w14", "sha256": "5b068fd4eb0f6336922952e085197660700b5d61c4d172e3c8a74432c9ad2557", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00004__wfv__package-root-mustunderstand-w14.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-mustunderstand-w14_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-mustunderstand-w14", "sha256": "5b068fd4eb0f6336922952e085197660700b5d61c4d172e3c8a74432c9ad2557", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00004__wfv__package-root-mustunderstand-w14.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-mustunderstand-w14_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "package-root-ignorable-child", "sha256": "2b8696a9abe9c30392e71590d5960c28b57cf08f28bc7c8babc4a33184c3fe79", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00002__wfv__package-root-ignorable-child.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-ignorable-child_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "package-root-ignorable-child", "sha256": "2b8696a9abe9c30392e71590d5960c28b57cf08f28bc7c8babc4a33184c3fe79", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00002__wfv__package-root-ignorable-child.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF package-root-ignorable-child_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 1, "name": "zz-s68b-control-last", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:21+00:00", "staged": "00007__wfv__zz-s68b-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68b-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68b", "pass": 2, "name": "zz-s68b-control-last", "sha256": "3159271c0d644744ba221d3a30be7ca80fd4c6a3fac7797657a7732b84c876e7", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:47:28+00:00", "staged": "00007__wfv__zz-s68b-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68b-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68c", "pass": 1, "name": "00-s68c-control-first", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00000__wfv__00-s68c-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68c-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68c", "pass": 2, "name": "00-s68c-control-first", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00000__wfv__00-s68c-control-first.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF 00-s68c-control-first_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68c", "pass": 1, "name": "chart-header-referenced", "sha256": "9295270440c6ce2a141667a75b8340f4a6e1b005b62dd7cf5ec7f7b67431435b", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00004__wfv__chart-header-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:47:54.691 'Word found unreadable content in 00004__wfv__chart-header-referenced.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:47:55.536 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__chart-header-referenced.docx)\""]}
{"run": "s68c", "pass": 2, "name": "chart-header-referenced", "sha256": "9295270440c6ce2a141667a75b8340f4a6e1b005b62dd7cf5ec7f7b67431435b", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00004__wfv__chart-header-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:40.261 'Word found unreadable content in 00004__wfv__chart-header-referenced.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:41.246 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__chart-header-referenced.docx)\""]}
{"run": "s68c", "pass": 1, "name": "chart-footnote-referenced", "sha256": "e6726a3858dad562b09603e6db5fe94663c562fc8cf98b3e885043d69de66c22", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00002__wfv__chart-footnote-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:47:46.089 'Word found unreadable content in 00002__wfv__chart-footnote-referenced.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:47:46.579 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-footnote-referenced...)\""]}
{"run": "s68c", "pass": 2, "name": "chart-footnote-referenced", "sha256": "e6726a3858dad562b09603e6db5fe94663c562fc8cf98b3e885043d69de66c22", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00002__wfv__chart-footnote-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:23.558 'Word found unreadable content in 00002__wfv__chart-footnote-referenced.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:24.446 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__chart-footnote-referenced...)\""]}
{"run": "s68c", "pass": 1, "name": "chart-glossary-referenced", "sha256": "68529f0b0e785513f2edf004be2d70958e17e527cbe91f1b9fded7a142c6fb24", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00003__wfv__chart-glossary-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:47:50.342 'Word found unreadable content in 00003__wfv__chart-glossary-referenced.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:47:51.151 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__chart-glossary-referenced...)\""]}
{"run": "s68c", "pass": 2, "name": "chart-glossary-referenced", "sha256": "68529f0b0e785513f2edf004be2d70958e17e527cbe91f1b9fded7a142c6fb24", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00003__wfv__chart-glossary-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:31.243 'Word found unreadable content in 00003__wfv__chart-glossary-referenced.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:32.147 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__chart-glossary-referenced...)\""]}
{"run": "s68c", "pass": 1, "name": "chart-selected-fallback", "sha256": "4151aa20fc39324819fde0c2015fcf5f8252cc458f75c64474392c6a119834d6", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00005__wfv__chart-selected-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:47:58.973 'Word found unreadable content in 00005__wfv__chart-selected-fallback.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:47:59.780 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__chart-selected-fallback.docx)\""]}
{"run": "s68c", "pass": 2, "name": "chart-selected-fallback", "sha256": "4151aa20fc39324819fde0c2015fcf5f8252cc458f75c64474392c6a119834d6", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00005__wfv__chart-selected-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:49.296 'Word found unreadable content in 00005__wfv__chart-selected-fallback.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:50.324 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__chart-selected-fallback.docx)\""]}
{"run": "s68c", "pass": 1, "name": "chart-two-relationships-one-reference", "sha256": "38692fa07ce8d1fcfd4a72bcf8192e9a1876b1a28a0b77f3cf88888e52554048", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00006__wfv__chart-two-relationships-one-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:03.156 'Word found unreadable content in 00006__wfv__chart-two-relationships-one-reference.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:03.731 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__chart-two-relationships-o...)\""]}
{"run": "s68c", "pass": 2, "name": "chart-two-relationships-one-reference", "sha256": "38692fa07ce8d1fcfd4a72bcf8192e9a1876b1a28a0b77f3cf88888e52554048", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00006__wfv__chart-two-relationships-one-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:56.976 'Word found unreadable content in 00006__wfv__chart-two-relationships-one-reference.docx. Do you wan … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:57.872 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00006__wfv__chart-two-relationships-o...)\""]}
{"run": "s68c", "pass": 1, "name": "chart-equivalent-target-referenced", "sha256": "a56b728ca9a3ab7bea131f935d4a156f04fd47b4d32678676539ea87750cb06e", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00001__wfv__chart-equivalent-target-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:47:41.507 'Word found unreadable content in 00001__wfv__chart-equivalent-target-referenced.docx. Do you want t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:47:42.291 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__chart-equivalent-target-r...)\""]}
{"run": "s68c", "pass": 2, "name": "chart-equivalent-target-referenced", "sha256": "a56b728ca9a3ab7bea131f935d4a156f04fd47b4d32678676539ea87750cb06e", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00001__wfv__chart-equivalent-target-referenced.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-26 21:48:19.358 'Word found unreadable content in 00001__wfv__chart-equivalent-target-referenced.docx. Do you want t … ? If you trust the source of this document, click Yes.'", "2026-10-26 21:48:20.227 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__chart-equivalent-target-r...)\""]}
{"run": "s68c", "pass": 1, "name": "zz-s68c-control-last", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:04+00:00", "staged": "00007__wfv__zz-s68c-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68c-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s68c", "pass": 2, "name": "zz-s68c-control-last", "sha256": "9f7a3eb4f36859a7ac39d96ad28fe62f0d0aee8ee29682fe374b8bf3b5ec07ca", "validatorRevision": "f4cd929e9a4075e110eed09dbe70703cd94ed792", "observedAt": "2026-10-27T01:48:58+00:00", "staged": "00007__wfv__zz-s68c-control-last.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF zz-s68c-control-last_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 68 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s68builder.mts`:

```ts
// Session 68: a two-run re-probe of session 39's three chunks (#661, #662), byte for byte, with the controls named so
// the driver's name-ordered queue opens one first and one last in every chunk. Session 39 ran each chunk once, before
// the two-runs-with-logs rule, and queued its controls last (#671).
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s68a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const { validate } = await import(path.join(process.cwd(), "src/scripts/office/validate.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

// Each session 68 chunk repeats one session 39 chunk.
const SOURCES: Record<string, string> = { s68a: "s39a", s68b: "s39b", s68c: "s39c" };

const chunk = process.env.CHUNK ?? "";
const source = SOURCES[chunk];
if (!source) throw new Error(`CHUNK must be one of ${Object.keys(SOURCES).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

type SourceRow = { name: string; issue: string; file: string; sha256: string };
const sourceRows: SourceRow[] = readFileSync(path.join(ROOT, source, "specimens.jsonl"), "utf8")
    .trim()
    .split("\n")
    .map((line) => JSON.parse(line));
const control = sourceRows.find((row) => row.name === `${source}-control-minimal`);
if (!control) throw new Error(`${source} has no ${source}-control-minimal row`);
const specimens = sourceRows.filter((row) => row.issue !== "control");
if (specimens.length !== 6) throw new Error(`${source}: expected 6 specimens, found ${specimens.length}`);

// [name, issue, the session 39 row whose bytes it copies]
const rows: Array<[string, string, SourceRow]> = [
    [`00-${chunk}-control-first`, "control", control],
    ...specimens.map((row): [string, string, SourceRow] => [row.name, `repeat of ${source}: ${row.issue}`, row]),
    [`zz-${chunk}-control-last`, "control", control],
];

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, from] of rows) {
    const bytes = readFileSync(path.join(ROOT, source, "src", from.file));
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    if (sha256 !== from.sha256) throw new Error(`${from.file}: stored bytes ${sha256} differ from session 39's ${from.sha256}`);
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: false,
        copiedFrom: `${source}/src/${from.file}`,
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `copied ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-68 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s68a", "s68b", "s68c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0]) if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s68/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-68 parts of docs/plans/evidence/word-probes-2026-10-24.md into s68/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s68a", "s68b", "s68c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s68/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

# Where each run opened its controls, from the driver's manifests (in open order, #671): the narrative states it, so
# check it here rather than trust the names' sort order.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert len(opened) == 8 and opened[0] == f"00-{label}-control-first.docx" and opened[-1] == f"zz-{label}-control-last.docx", (run, opened)
# The narrative's claims about outcomes, checked against results.json.
for (label, file), r in results.items():
    if r["control"] or label != "s68c":
        assert r["outcome"] == "clean-open", (label, file, r["outcome"])
    else:
        assert r["outcome"] == "unreadable-content-warning", (label, file, r["outcome"])
    assert r["validatorMatchesWord"], (label, file)
assert agreed == len(rows) == 24, (agreed, len(rows))
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
out = [
    f"### Session 68: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "A two-run repeat of session 39 ([#661](https://github.com/jandira-tech/docx-validate/issues/661), "
    "[#662](https://github.com/jandira-tech/docx-validate/issues/662)). Session 39 ran each chunk once, before the "
    "two-runs-with-logs rule, and its controls were queued last in every chunk ([#671](https://github.com/jandira-tech/docx-validate/issues/671)). "
    "Here each chunk holds session 39's six specimens, copied byte for byte (the builder checks every SHA-256 against "
    "session 39's row), and its minimal control twice, named so the driver's name-ordered queue opens one copy first and "
    "the other last; every run's manifest shows the controls opened 1st and 8th of 8. Each chunk ran twice, as two separate "
    "driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's "
    "`logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, "
    f"and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and "
    "second runs. Shape repeats session 39's description. The builder recorded the validator revision in every row "
    f"(`{rev}`).",
    "",
    "- **Chart sources (s68a, #661).** The six unreferenced chart shapes, clean in session 39, open clean in both runs: "
    "a chart related from a referenced header's sidecar, from a reached glossary's footnotes part's sidecar and from the "
    "glossary document's sidecar, a chart whose only drawing sits in an unselected Fallback, a chart related twice and "
    "named by neither, and a chart related through an equivalent target spelling.",
    "- **Package-root wrappers (s68b, #662).** The six compound `_rels/.rels` root wrappers, clean in session 39, open "
    "clean in both runs.",
    "- **Referenced chart twins (s68c, #661).** Each of the six referenced twins gets the recovery offer in both runs, as "
    "in session 39.",
    "",
    "Session 39's verdicts stand, now from two runs whose controls bracket the specimens. Word-valid matches Word on all "
    "24 rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 68</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 68 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s68builder.mts", ROOT / "s68builder.mts", "ts"), ("compare.py", ROOT / "s68/compare.py", "python"),
                         ("section.py", ROOT / "s68/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s68/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 69: 05:01Z–05:01Z on 2026-10-27, validator columns at bc09dc1d

The open question of [#896](https://github.com/jandira-tech/docx-validate/issues/896): whether a comments part that no relationship names defines the comment the body references. At this revision the comment checks fell back to `word/comments.xml` by name whenever no relationship of the main document named a comments part. Session 61 refused the notes twin. One chunk, with the minimal control twice. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 8 of 8 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd`).

The driver opens files in name order, and the control names sort last, so both runs opened the two controls 7th and 8th, after every specimen, not one first and one last as in session 68. The two calibrations opened 2nd and 6th, on either side of the two refused rows (3rd and 5th), and opened clean in both runs, so Word opened packages clean before and after each refusal.

- **(a), (b).** A body `w:commentReference` to comment 0, which only a `word/comments.xml` typed comments by its Override but named by no relationship defines, gets the recovery offer, both with no `word/_rels/document.xml.rels` and beside one relating only `styles.xml`. Word-valid at bc09dc1d accepts both: two false negatives, from the by-name fallback.
- **(c) and the no-sidecar calibration.** The same package with a comments relationship naming the part opens clean, and so does the minimal package with no main-document relationships part and no comments.
- **(d).** Row (b) with the range markers only, no `w:commentReference`, opens clean. Range markers naming no comment stay word-valid warnings (#784), so this row is consistent with Word reading no comments part.
- **#895.** The no-relationships tree after layer 242's `addComment` for comment 0, which creates `word/_rels/document.xml.rels` and relates and types its four comment parts, opens clean with the body then marked.

Word defines comments only from the part a `comments` relationship names, as session 61 showed for notes. Word-valid at bc09dc1d matches Word on 6 of 8 rows.

| Run    | Observed             | Specimen                        | Shape                                                                                                                                                                 | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at bc09dc1d | strict at bc09dc1d                                                                      |
| ------ | -------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | --------------------------------------------------------------------------------------- |
| `s69a` | 05:01:21Z, 05:01:43Z | `s69a-control-minimal`          | control                                                                                                                                                               | `a48d5d56efc5f279` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                   |
| `s69a` | 05:01:21Z, 05:01:43Z | `no-sidecar-calibration`        | calibration: the minimal package with no word/_rels/document.xml.rels (styles.xml and its Override removed too); no comments                                          | `a0022ea217743491` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                   |
| `s69a` | 05:01:21Z, 05:01:43Z | `comments-unrelated-no-sidecar` | (a) no word/_rels/document.xml.rels; word/comments.xml defines comment 0 (typed comments); the body marks its range and references it                                 | `ecb58be137353ee3` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element`                                  |
| `s69a` | 05:01:21Z, 05:01:43Z | `comments-unrelated-sidecar`    | (b) word/_rels/document.xml.rels relates only styles.xml; word/comments.xml defines comment 0 (typed comments); the body marks its range and references it            | `8cf51fe50aea75e3` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `paraid-missing-element`                                  |
| `s69a` | 05:01:21Z, 05:01:43Z | `comments-related-calibration`  | (c) calibration: the same package with a comments relationship naming word/comments.xml                                                                               | `0faa70dd0017e774` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element`                                                       |
| `s69a` | 05:01:21Z, 05:01:43Z | `comments-unrelated-range-only` | (d) row (b) with the range markers only, no w:commentReference                                                                                                        | `eccc32180b53f9ce` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-unreferenced`, `comment-thread-count-mismatch`, `paraid-missing-element` |
| `s69a` | 05:01:21Z, 05:01:43Z | `addcomment-created-sidecar`    | #895: the no-relationships tree after layer 242's addComment for comment 0 (it creates word/_rels/document.xml.rels and its four comment parts), then the body marked | `0f3958a89c064d8a` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `style-reference-undefined`                                                    |
| `s69a` | 05:01:21Z, 05:01:43Z | `s69a-control-minimal-end`      | control                                                                                                                                                               | `a48d5d56efc5f279` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                   |

<details><summary>Raw records, session 69</summary>

```jsonl
{"run": "s69a", "pass": 1, "name": "s69a-control-minimal", "sha256": "a48d5d56efc5f2794e68345ba4883d90328a85faf9f10de08ee81ee5adc02c54", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00007__wfv__s69a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s69a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "s69a-control-minimal", "sha256": "a48d5d56efc5f2794e68345ba4883d90328a85faf9f10de08ee81ee5adc02c54", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00007__wfv__s69a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s69a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 1, "name": "no-sidecar-calibration", "sha256": "a0022ea21774349181afb8d13f68db00feeac00fcdcd3ad799a2b94c77c1ba3d", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00005__wfv__no-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF no-sidecar-calibration_byword.pdf (8282 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "no-sidecar-calibration", "sha256": "a0022ea21774349181afb8d13f68db00feeac00fcdcd3ad799a2b94c77c1ba3d", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00005__wfv__no-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF no-sidecar-calibration_byword.pdf (8282 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 1, "name": "comments-unrelated-no-sidecar", "sha256": "ecb58be137353ee3a145a6807dbc34f770ffa7ae6a49e98dc8410dc5743c9ec4", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00002__wfv__comments-unrelated-no-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 01:01:14.908 'Word found unreadable content in 00002__wfv__comments-unrelated-no-sidecar.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-27 01:01:15.702 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__comments-unrelated-no-sid...)\""]}
{"run": "s69a", "pass": 2, "name": "comments-unrelated-no-sidecar", "sha256": "ecb58be137353ee3a145a6807dbc34f770ffa7ae6a49e98dc8410dc5743c9ec4", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00002__wfv__comments-unrelated-no-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 01:01:37.485 'Word found unreadable content in 00002__wfv__comments-unrelated-no-sidecar.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-27 01:01:37.974 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__comments-unrelated-no-sid...)\""]}
{"run": "s69a", "pass": 1, "name": "comments-unrelated-sidecar", "sha256": "8cf51fe50aea75e372ce266b7402d7a9cc82c51b0fe40f444b47d6211e5b190e", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00004__wfv__comments-unrelated-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 01:01:19.235 'Word found unreadable content in 00004__wfv__comments-unrelated-sidecar.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-27 01:01:19.768 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__comments-unrelated-sideca...)\""]}
{"run": "s69a", "pass": 2, "name": "comments-unrelated-sidecar", "sha256": "8cf51fe50aea75e372ce266b7402d7a9cc82c51b0fe40f444b47d6211e5b190e", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00004__wfv__comments-unrelated-sidecar.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 01:01:41.703 'Word found unreadable content in 00004__wfv__comments-unrelated-sidecar.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-27 01:01:42.202 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__comments-unrelated-sideca...)\""]}
{"run": "s69a", "pass": 1, "name": "comments-related-calibration", "sha256": "0faa70dd0017e77457f27bd2ddca40af4019315f73248979f0e81e5c5c983478", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00001__wfv__comments-related-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-related-calibration_byword.pdf (36447 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "comments-related-calibration", "sha256": "0faa70dd0017e77457f27bd2ddca40af4019315f73248979f0e81e5c5c983478", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00001__wfv__comments-related-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-related-calibration_byword.pdf (36447 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 1, "name": "comments-unrelated-range-only", "sha256": "eccc32180b53f9cef1818a8ae31a74e1c58799debda731abfd0f4548a6739f89", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00003__wfv__comments-unrelated-range-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-unrelated-range-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "comments-unrelated-range-only", "sha256": "eccc32180b53f9cef1818a8ae31a74e1c58799debda731abfd0f4548a6739f89", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00003__wfv__comments-unrelated-range-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-unrelated-range-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 1, "name": "addcomment-created-sidecar", "sha256": "0f3958a89c064d8a62a6a5e8670cfe8ec59f9adda7b3086ae3fe55a8f68d16eb", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00000__wfv__addcomment-created-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF addcomment-created-sidecar_byword.pdf (24928 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "addcomment-created-sidecar", "sha256": "0f3958a89c064d8a62a6a5e8670cfe8ec59f9adda7b3086ae3fe55a8f68d16eb", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00000__wfv__addcomment-created-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF addcomment-created-sidecar_byword.pdf (24928 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 1, "name": "s69a-control-minimal-end", "sha256": "a48d5d56efc5f2794e68345ba4883d90328a85faf9f10de08ee81ee5adc02c54", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:21+00:00", "staged": "00006__wfv__s69a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s69a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s69a", "pass": 2, "name": "s69a-control-minimal-end", "sha256": "a48d5d56efc5f2794e68345ba4883d90328a85faf9f10de08ee81ee5adc02c54", "validatorRevision": "bc09dc1dc98f69fcf522dd2a9b2e883afea5a1cd", "observedAt": "2026-10-27T05:01:43+00:00", "staged": "00006__wfv__s69a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s69a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 69 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s69builder.mts`:

```ts
// Session 69 (2026-10-27): does Word read a comments part no relationship names (#896)?
// The comment checks fall back to word/comments.xml by name when no relationship of the main document names a comments
// part, so a body w:commentReference to a comment only that part defines draws no comment-marker-missing. Session 61
// refused the notes twin (a note only an unrelated word/footnotes.xml defines). This chunk asks the same of comments,
// with and without a main-document relationships part, and checks the part #895's addComment fix now creates.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s69a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { promises as fs } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { addComment } = await import(path.join(WT, "src/scripts/comment.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const HELLO = "<w:r><w:t>Hello</w:t></w:r>";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The main document with comment 0's range around "Hello", and its w:commentReference when `reference`. */
const marked = (main: string, reference: boolean) =>
    replaceOnce(
        main,
        HELLO,
        `<w:commentRangeStart w:id="0"/>${HELLO}<w:commentRangeEnd w:id="0"/>${reference ? `<w:r><w:commentReference w:id="0"/></w:r>` : ""}`,
    );
const COMMENTS_XML = `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a" w:initials="a"><w:p><w:r><w:t>Comment</w:t></w:r></w:p></w:comment></w:comments>`;

/** The minimal parts with no main-document relationships part; styles.xml and its Override go too, so nothing is left unrelated. */
const noSidecar = (): Record<string, string> => {
    const next: Record<string, string> = {
        ...P,
        [CT]: replaceOnce(P[CT]!, `<Override PartName="/word/styles.xml" ContentType="${WML}.styles+xml"/>`, ""),
    };
    delete next[SIDECAR];
    delete next["word/styles.xml"];
    return next;
};
/** `parts` with word/comments.xml (comment 0, typed comments), related by the main document when `related`, and the body marked. */
const withComments = (parts: Record<string, string>, related: boolean, reference: boolean): Record<string, string> => {
    const next: Record<string, string> = {
        ...parts,
        "word/comments.xml": COMMENTS_XML,
        [CT]: overrides(parts[CT]!, ["word/comments.xml", `${WML}.comments+xml`]),
        [MAIN]: marked(parts[MAIN]!, reference),
    };
    if (related) next[SIDECAR] = appendRels(parts[SIDECAR]!, relationship("rIdC", "comments", "comments.xml"));
    return next;
};

/** The parts as `addComment` leaves them for a first comment on the no-relationships tree, with the body then marked (#895). */
const viaAddComment = async (chunk: string): Promise<Record<string, string>> => {
    const work = path.join(ROOT, chunk, "work");
    rmSync(work, { recursive: true, force: true });
    for (const [name, text] of Object.entries(noSidecar())) {
        mkdirSync(path.dirname(path.join(work, name)), { recursive: true });
        writeFileSync(path.join(work, name), text);
    }
    const result = await addComment({
        unpackedDir: work,
        commentId: 0,
        text: "Comment",
        author: "a",
        initials: "a",
        date: new Date(Date.UTC(2026, 9, 27, 0, 0, 0)),
    });
    if (!result.message.startsWith("Added comment 0")) throw new Error(`addComment: ${result.message}`);
    const parts: Record<string, string> = {};
    const walk = async (dir: string): Promise<void> => {
        for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
            const full = path.join(dir, entry.name);
            if (entry.isDirectory()) await walk(full);
            else parts[path.relative(work, full)] = await fs.readFile(full, "utf8");
        }
    };
    await walk(work);
    parts[MAIN] = marked(parts[MAIN]!, true);
    return parts;
};

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s69a: withControls("s69a", [
        [
            "no-sidecar-calibration",
            "calibration: the minimal package with no word/_rels/document.xml.rels (styles.xml and its Override removed too); no comments",
            () => buildDocx(noSidecar()),
        ],
        [
            "comments-unrelated-no-sidecar",
            "(a) no word/_rels/document.xml.rels; word/comments.xml defines comment 0 (typed comments); the body marks its range and references it",
            () => buildDocx(withComments(noSidecar(), false, true)),
        ],
        [
            "comments-unrelated-sidecar",
            "(b) word/_rels/document.xml.rels relates only styles.xml; word/comments.xml defines comment 0 (typed comments); the body marks its range and references it",
            () => buildDocx(withComments({ ...P }, false, true)),
        ],
        [
            "comments-related-calibration",
            "(c) calibration: the same package with a comments relationship naming word/comments.xml",
            () => buildDocx(withComments({ ...P }, true, true)),
        ],
        [
            "comments-unrelated-range-only",
            "(d) row (b) with the range markers only, no w:commentReference",
            () => buildDocx(withComments({ ...P }, false, false)),
        ],
        [
            "addcomment-created-sidecar",
            "#895: the no-relationships tree after layer 242's addComment for comment 0 (it creates word/_rels/document.xml.rels and its four comment parts), then the body marked",
            async () => buildDocx(await viaAddComment("s69a")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-69 chunk: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s69a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s69/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-69 parts of docs/plans/evidence/word-probes-2026-10-24.md into s69/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796).
"""
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s69a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s69/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = ("comments-unrelated-no-sidecar.docx", "comments-unrelated-sidecar.docx")
# Where each run opened each row, from the driver's manifests (in open order, #671): the narrative states it, so check it
# here rather than trust the names' sort order. The control names sort last, so both controls opened after every specimen.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert len(opened) == 8, (run, opened)
        assert opened[6:] == [f"{label}-control-minimal-end.docx", f"{label}-control-minimal.docx"], (run, opened)
        assert opened[1] == "comments-related-calibration.docx" and opened[5] == "no-sidecar-calibration.docx", (run, opened)
        assert (opened[2], opened[4]) == REFUSED, (run, opened)
# The narrative's claims about outcomes, checked against results.json.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning" and r["wordValid"] is True and not r["validatorMatchesWord"], (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 8, (agreed, len(rows))
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
out = [
    f"### Session 69: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The open question of [#896](https://github.com/jandira-tech/docx-validate/issues/896): whether a comments part that "
    "no relationship names defines the comment the body references. At this revision the comment checks fell back to "
    "`word/comments.xml` by name whenever no relationship of the main document named a comments part. Session 61 refused "
    "the notes twin. One chunk, with the minimal control twice. It ran twice, as two separate driver runs of byte-identical "
    "copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    f"`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    f"Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, and the control names sort last, so both runs opened the two controls 7th and "
    "8th, after every specimen, not one first and one last as in session 68. The two calibrations opened 2nd and 6th, on "
    "either side of the two refused rows (3rd and 5th), and opened clean in both runs, so Word opened packages clean before "
    "and after each refusal.",
    "",
    "- **(a), (b).** A body `w:commentReference` to comment 0, which only a `word/comments.xml` typed comments by its "
    "Override but named by no relationship defines, gets the recovery offer, both with no `word/_rels/document.xml.rels` "
    f"and beside one relating only `styles.xml`. Word-valid at {at} accepts both: two false negatives, from the by-name "
    "fallback.",
    "- **(c) and the no-sidecar calibration.** The same package with a comments relationship naming the part opens clean, "
    "and so does the minimal package with no main-document relationships part and no comments.",
    "- **(d).** Row (b) with the range markers only, no `w:commentReference`, opens clean. Range markers naming no "
    "comment stay word-valid warnings (#784), so this row is consistent with Word reading no comments part.",
    "- **#895.** The no-relationships tree after layer 242's `addComment` for comment 0, which creates "
    "`word/_rels/document.xml.rels` and relates and types its four comment parts, opens clean with the body then marked.",
    "",
    "Word defines comments only from the part a `comments` relationship names, as session 61 showed for notes. Word-valid "
    f"at {at} matches Word on 6 of 8 rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 69</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 69 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s69builder.mts", ROOT / "s69builder.mts", "ts"), ("compare.py", ROOT / "s69/compare.py", "python"),
                         ("section.py", ROOT / "s69/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s69/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 70: 21:41Z–21:47Z on 2026-10-27, validator columns at f2fe8fe3

The open question of [#962](https://github.com/jandira-tech/docx-validate/issues/962): how Word resolves a relationship target with an empty segment or a final dot segment. At this revision `relationshipTargetPartName` resolved a target as `path.posix.join` does, which collapses an empty segment and drops the final `/` that RFC 3986's remove_dot_segments leaves after a final `.` or `..` segment, so `word/main.xml/.` and `word/main.xml/x/..` named `word/main.xml`. Three chunks: s70a asks with the `officeDocument` target of a main document stored as `word/main.xml`, s70b with a `footnotes` target whose note 1 the body references (a note no part defines dangles, and Word offers recovery for it, session 61), and s70c, added after the first two ran, with the other spellings whose RFC 3986 path ends in `/`. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 18 of 18 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d`).

The driver opens files in name order, and the control names sort last, so in every run both minimal controls opened after every specimen, and clean. Each run also opened a row clean after its refused rows: s70a's calibration opened 5th, after the refused 2nd and 4th; s70b's opened 3rd, after the refused 2nd; and s70c's inner-dot calibration opened 2nd, between the refused 1st and 3rd. Every clean row's PDF holds the text the specimen stores: `Hello` for the main document, and `Hello1 Note` (footnote 1) for the notes rows (`pdftotext`, both runs).

- **An empty segment collapses.** `word//main.xml`, the package-absolute `/word//main.xml`, and the footnotes target `notes//footnotes.xml` open clean, with the main document and the note rendered, as the plain calibrations do: Word reads the part through the target, as `path.posix.join` collapses it, where RFC 3986 would keep the empty segment.
- **An inner `.` resolves.** `word/./main.xml` opens clean with the main document rendered.
- **A final `.` or `..` segment leaves a folder.** `word/main.xml/.`, `/word/main.xml/.`, `word/main.xml/x/..`, and the footnotes targets `notes/footnotes.xml/.` and `notes/footnotes.xml/x/..` get the recovery offer, as `word/main.xml/` with its trailing `/` does: the RFC 3986 path names a folder, and Word reads no part through it. Word-valid at f2fe8fe3 accepts the five final-segment rows, five false negatives from the dropped `/`, and rejects `word/main.xml/` with `word-main-document-part`.

Word resolves a target's dot segments as RFC 3986 does, but collapses an empty segment. Word-valid at f2fe8fe3 matches Word on 13 of 18 rows.

| Run    | Observed             | Specimen                      | Shape                                                                                                                                                                                                                          | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at f2fe8fe3             | strict at f2fe8fe3                 |
| ------ | -------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------- | ---------------------------------- |
| `s70a` | 21:41:38Z, 21:42:18Z | `s70a-control-minimal`        | control                                                                                                                                                                                                                        | `4ed2cced72e9be03` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `main-plain-calibration`      | calibration: the main document stored as word/main.xml, named by the officeDocument target word/main.xml                                                                                                                       | `a20a583eaf725368` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `main-empty-segment`          | #962: the same, named by word//main.xml (path.posix.join: word/main.xml; RFC 3986: word//main.xml, no part)                                                                                                                    | `fe92e6c3c1634645` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `main-absolute-empty-segment` | #962: the same, named by /word//main.xml                                                                                                                                                                                       | `5d37437c0f5a4b98` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `main-final-dot`              | #962: the same, named by word/main.xml/. (path.posix.join: word/main.xml; RFC 3986: word/main.xml/, no part)                                                                                                                   | `ec57d5b793fed074` | repair-warning | repair-warning | unreadable-content-warning | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `main-absolute-final-dot`     | #962: the same, named by /word/main.xml/.                                                                                                                                                                                      | `1f7f7310d0cec797` | repair-warning | repair-warning | unreadable-content-warning | valid                              | valid                              |
| `s70a` | 21:41:38Z, 21:42:18Z | `s70a-control-minimal-end`    | control                                                                                                                                                                                                                        | `d976a5fd7d21ed45` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70b` | 21:42:42Z, 21:43:12Z | `s70b-control-minimal`        | control                                                                                                                                                                                                                        | `11d2c4d88cb95839` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70b` | 21:42:42Z, 21:43:12Z | `notes-plain-calibration`     | calibration: footnote 1 in word/notes/footnotes.xml, named by the footnotes target notes/footnotes.xml; the body references footnote 1                                                                                         | `0c91ac1aeb311d88` | clean-open     | clean-open     | clean-open                 | valid                              | invalid: `paraid-missing-element`  |
| `s70b` | 21:42:42Z, 21:43:12Z | `notes-empty-segment`         | #962: the same, named by notes//footnotes.xml (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes//footnotes.xml, no part)                                                                                        | `3fd4940badb95206` | clean-open     | clean-open     | clean-open                 | valid                              | invalid: `paraid-missing-element`  |
| `s70b` | 21:42:42Z, 21:43:12Z | `notes-final-dot`             | #962: the same, named by notes/footnotes.xml/. (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes/footnotes.xml/, no part)                                                                                       | `def0f7037758ef92` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `paraid-missing-element`  |
| `s70b` | 21:42:42Z, 21:43:12Z | `s70b-control-minimal-end`    | control                                                                                                                                                                                                                        | `6f04caac7c88ea17` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70c` | 21:46:21Z, 21:47:55Z | `s70c-control-minimal`        | control                                                                                                                                                                                                                        | `e4177e9d37d0ca03` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70c` | 21:46:21Z, 21:47:55Z | `main-inner-dot-calibration`  | calibration: the main document stored as word/main.xml, named by word/./main.xml (path.posix.join and RFC 3986 alike: word/main.xml)                                                                                           | `77d3ecbc531009be` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |
| `s70c` | 21:46:21Z, 21:47:55Z | `main-final-dotdot`           | #962: the same, named by word/main.xml/x/.. (path.posix.join: word/main.xml; RFC 3986: word/main.xml/, no part)                                                                                                                | `ba127588479f2d4f` | repair-warning | repair-warning | unreadable-content-warning | valid                              | valid                              |
| `s70c` | 21:46:21Z, 21:47:55Z | `main-trailing-slash`         | #962: the same, named by word/main.xml/ (path.posix.join and RFC 3986 alike: word/main.xml/, no part)                                                                                                                          | `920fe68cfdca70a1` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-main-document-part` | invalid: `word-main-document-part` |
| `s70c` | 21:46:21Z, 21:47:55Z | `notes-final-dotdot`          | #962: footnote 1 in word/notes/footnotes.xml, named by the footnotes target notes/footnotes.xml/x/.. (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes/footnotes.xml/, no part); the body references footnote 1 | `c06ffe3cfb2f4c98` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `paraid-missing-element`  |
| `s70c` | 21:46:21Z, 21:47:55Z | `s70c-control-minimal-end`    | control                                                                                                                                                                                                                        | `e4177e9d37d0ca03` | clean-open     | clean-open     | clean-open                 | valid                              | valid                              |

<details><summary>Raw records, session 70</summary>

```jsonl
{"run": "s70a", "pass": 1, "name": "s70a-control-minimal", "sha256": "4ed2cced72e9be03c4a8e5694e7c5c797a809322effde444ffc75b48c1a3ab31", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00006__wfv__s70a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 2, "name": "s70a-control-minimal", "sha256": "4ed2cced72e9be03c4a8e5694e7c5c797a809322effde444ffc75b48c1a3ab31", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00006__wfv__s70a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 1, "name": "main-plain-calibration", "sha256": "a20a583eaf725368b7d5fd0bdfd4c4658499a6023a7231b907877e3b66588f7d", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00004__wfv__main-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 2, "name": "main-plain-calibration", "sha256": "a20a583eaf725368b7d5fd0bdfd4c4658499a6023a7231b907877e3b66588f7d", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00004__wfv__main-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 1, "name": "main-empty-segment", "sha256": "fe92e6c3c1634645c74adb369584af00db1c51d6e61fe716c8033120d1e686d7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00002__wfv__main-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-empty-segment_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 2, "name": "main-empty-segment", "sha256": "fe92e6c3c1634645c74adb369584af00db1c51d6e61fe716c8033120d1e686d7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00002__wfv__main-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-empty-segment_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 1, "name": "main-absolute-empty-segment", "sha256": "5d37437c0f5a4b980093bfa4c76316a53d1d6c7e4d9e17a70976c84faed1f719", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00000__wfv__main-absolute-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-absolute-empty-segment_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 2, "name": "main-absolute-empty-segment", "sha256": "5d37437c0f5a4b980093bfa4c76316a53d1d6c7e4d9e17a70976c84faed1f719", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00000__wfv__main-absolute-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-absolute-empty-segment_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 1, "name": "main-final-dot", "sha256": "ec57d5b793fed074899dfbbfa612a106c0fcb4991e8546f4bb6843d3c0e66a1f", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00003__wfv__main-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:41:36.402 'Word found unreadable content in 00003__wfv__main-final-dot.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-27 17:41:36.940 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00003__wfv__main-final-dot.docx)\""]}
{"run": "s70a", "pass": 2, "name": "main-final-dot", "sha256": "ec57d5b793fed074899dfbbfa612a106c0fcb4991e8546f4bb6843d3c0e66a1f", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00003__wfv__main-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:42:16.654 \"Word found unreadable content in 00003__wfv__main-final-dot.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70a", "pass": 1, "name": "main-absolute-final-dot", "sha256": "1f7f7310d0cec797caa3e7da524c1aeedaeb285f6cf9eca05c367a95d8917f2a", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00001__wfv__main-absolute-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:41:01.425 \"Word found unreadable content in 00001__wfv__main-absolute-final-dot.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70a", "pass": 2, "name": "main-absolute-final-dot", "sha256": "1f7f7310d0cec797caa3e7da524c1aeedaeb285f6cf9eca05c367a95d8917f2a", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00001__wfv__main-absolute-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:42:04.056 \"Word found unreadable content in 00001__wfv__main-absolute-final-dot.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70a", "pass": 1, "name": "s70a-control-minimal-end", "sha256": "d976a5fd7d21ed458297e58fa8452e50b55d975b46c68ba51dc6575555ae8052", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:41:38+00:00", "staged": "00005__wfv__s70a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70a", "pass": 2, "name": "s70a-control-minimal-end", "sha256": "d976a5fd7d21ed458297e58fa8452e50b55d975b46c68ba51dc6575555ae8052", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:18+00:00", "staged": "00005__wfv__s70a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 1, "name": "s70b-control-minimal", "sha256": "11d2c4d88cb95839ff38650816d33bb5e9ad14484ff834a65aa4c22153b6fc8f", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:42+00:00", "staged": "00004__wfv__s70b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 2, "name": "s70b-control-minimal", "sha256": "11d2c4d88cb95839ff38650816d33bb5e9ad14484ff834a65aa4c22153b6fc8f", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:43:12+00:00", "staged": "00004__wfv__s70b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 1, "name": "notes-plain-calibration", "sha256": "0c91ac1aeb311d88c269da9d039eab759e93019f9e7c9e104b86faeb0c117a2b", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:42+00:00", "staged": "00002__wfv__notes-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-plain-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 2, "name": "notes-plain-calibration", "sha256": "0c91ac1aeb311d88c269da9d039eab759e93019f9e7c9e104b86faeb0c117a2b", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:43:12+00:00", "staged": "00002__wfv__notes-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-plain-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 1, "name": "notes-empty-segment", "sha256": "3fd4940badb95206d7ea93e50a0f93bb77644ed0ac681290b0464775781aa0f5", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:42+00:00", "staged": "00000__wfv__notes-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-empty-segment_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 2, "name": "notes-empty-segment", "sha256": "3fd4940badb95206d7ea93e50a0f93bb77644ed0ac681290b0464775781aa0f5", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:43:12+00:00", "staged": "00000__wfv__notes-empty-segment.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-empty-segment_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 1, "name": "notes-final-dot", "sha256": "def0f7037758ef92f3f73dcceea145b06dd961b7ac5900881f5679d27652da05", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:42+00:00", "staged": "00001__wfv__notes-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:42:41.092 \"Word found unreadable content in 00001__wfv__notes-final-dot.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70b", "pass": 2, "name": "notes-final-dot", "sha256": "def0f7037758ef92f3f73dcceea145b06dd961b7ac5900881f5679d27652da05", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:43:12+00:00", "staged": "00001__wfv__notes-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:43:10.794 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ecovery converter.\\n(00001__wfv__notes-final-dot.docx)'", "2026-10-27 17:43:10.918 \"Word found unreadable content in 00001__wfv__notes-final-dot.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70b", "pass": 1, "name": "s70b-control-minimal-end", "sha256": "6f04caac7c88ea17b6d75e403fac9932f9f157480bc0f22365f345a49444a5f7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:42:42+00:00", "staged": "00003__wfv__s70b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70b", "pass": 2, "name": "s70b-control-minimal-end", "sha256": "6f04caac7c88ea17b6d75e403fac9932f9f157480bc0f22365f345a49444a5f7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:43:12+00:00", "staged": "00003__wfv__s70b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 1, "name": "s70c-control-minimal", "sha256": "e4177e9d37d0ca03cec2c19144c6e16ad2ac59606564892807a601ad6664970e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00005__wfv__s70c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 2, "name": "s70c-control-minimal", "sha256": "e4177e9d37d0ca03cec2c19144c6e16ad2ac59606564892807a601ad6664970e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00005__wfv__s70c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 1, "name": "main-inner-dot-calibration", "sha256": "77d3ecbc531009bed53ebd98430f474afaac57a5f837b108fb139b8bacb058da", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00001__wfv__main-inner-dot-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-inner-dot-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 2, "name": "main-inner-dot-calibration", "sha256": "77d3ecbc531009bed53ebd98430f474afaac57a5f837b108fb139b8bacb058da", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00001__wfv__main-inner-dot-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-inner-dot-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 1, "name": "main-final-dotdot", "sha256": "ba127588479f2d4fa5f2b296935d80d6c9342cd291c4e29cc1fbe29251dc4da7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00000__wfv__main-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:45:12.907 \"Word found unreadable content in 00000__wfv__main-final-dotdot.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70c", "pass": 2, "name": "main-final-dotdot", "sha256": "ba127588479f2d4fa5f2b296935d80d6c9342cd291c4e29cc1fbe29251dc4da7", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00000__wfv__main-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:46:43.940 \"Word found unreadable content in 00000__wfv__main-final-dotdot.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70c", "pass": 1, "name": "main-trailing-slash", "sha256": "920fe68cfdca70a194aab2de4be0390004fb3b6b1cb441cb1b7a3b6c5dd4b83e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00002__wfv__main-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:45:29.643 \"Word found unreadable content in 00002__wfv__main-trailing-slash.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70c", "pass": 2, "name": "main-trailing-slash", "sha256": "920fe68cfdca70a194aab2de4be0390004fb3b6b1cb441cb1b7a3b6c5dd4b83e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00002__wfv__main-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:46:58.624 \"Word found unreadable content in 00002__wfv__main-trailing-slash.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""]}
{"run": "s70c", "pass": 1, "name": "notes-final-dotdot", "sha256": "c06ffe3cfb2f4c980f397f060905cf8e6316336786de9dc4dc87d95fce8bd47b", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00003__wfv__notes-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:46:19.580 Microsoft Word, Word found unreadable content in 00003__wfv__notes-final-dotdot.docx. Do you want to … t? If you trust the source of this document, click Yes.", "2026-10-27 17:46:20.257 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00003__wfv__notes-final-dotdot.docx)\""]}
{"run": "s70c", "pass": 2, "name": "notes-final-dotdot", "sha256": "c06ffe3cfb2f4c980f397f060905cf8e6316336786de9dc4dc87d95fce8bd47b", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00003__wfv__notes-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 17:47:54.225 'Word found unreadable content in 00003__wfv__notes-final-dotdot.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'"]}
{"run": "s70c", "pass": 1, "name": "s70c-control-minimal-end", "sha256": "e4177e9d37d0ca03cec2c19144c6e16ad2ac59606564892807a601ad6664970e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:46:21+00:00", "staged": "00004__wfv__s70c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s70c", "pass": 2, "name": "s70c-control-minimal-end", "sha256": "e4177e9d37d0ca03cec2c19144c6e16ad2ac59606564892807a601ad6664970e", "validatorRevision": "f2fe8fe3c7495bdbccb69cb6c722dc55fd4de90d", "observedAt": "2026-10-27T21:47:55+00:00", "staged": "00004__wfv__s70c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s70c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 70 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s70builder.mts`:

```ts
// Session 70 (2026-10-27): does Word collapse an empty segment and a final `/.` in a relationship target (#962)?
// relationshipTargetPartName resolves a target with path.posix.join, which collapses `word//main.xml` to `word/main.xml`
// and drops a final `/.`, so `word/main.xml/.` names `word/main.xml` too; RFC 3986's remove_dot_segments keeps the empty
// segment and leaves `word/main.xml/`, which names no part. s70a asks Word with the officeDocument target of a main
// document stored as word/main.xml (relative and package-absolute spellings), s70b with a footnotes target whose note
// the body references: if Word reads no notes part through the target, the reference dangles and Word offers recovery
// (session 61), so a clean open shows the target named the part.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s70a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The minimal parts with the main document stored as word/main.xml (its sidecar renamed, its Override moved) and named by the officeDocument target `target`. */
const mainAt = (target: string): Record<string, string> => {
    const next: Record<string, string> = { ...P, "word/main.xml": P[MAIN]!, "word/_rels/main.xml.rels": P[SIDECAR]! };
    delete next[MAIN];
    delete next[SIDECAR];
    next["_rels/.rels"] = replaceOnce(P["_rels/.rels"]!, 'Target="word/document.xml"', `Target="${target}"`);
    next[CT] = replaceOnce(P[CT]!, 'PartName="/word/document.xml"', 'PartName="/word/main.xml"');
    return next;
};

/** The minimal parts with footnote 1 stored in word/notes/footnotes.xml (typed footnotes), named by the main document's footnotes target `target`; the body references footnote 1. */
const notesAt = (target: string): Record<string, string> => ({
    ...P,
    [MAIN]: replaceOnce(P[MAIN]!, "</w:r></w:p>", `</w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p>`),
    "word/notes/footnotes.xml": `${XML_DECL}<w:footnotes xmlns:w="${W}"><w:footnote w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:footnote></w:footnotes>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", target)),
    [CT]: overrides(P[CT]!, ["word/notes/footnotes.xml", `${WML}.footnotes+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s70a: withControls("s70a", [
        [
            "main-plain-calibration",
            "calibration: the main document stored as word/main.xml, named by the officeDocument target word/main.xml",
            () => buildDocx(mainAt("word/main.xml")),
        ],
        [
            "main-empty-segment",
            "#962: the same, named by word//main.xml (path.posix.join: word/main.xml; RFC 3986: word//main.xml, no part)",
            () => buildDocx(mainAt("word//main.xml")),
        ],
        ["main-absolute-empty-segment", "#962: the same, named by /word//main.xml", () => buildDocx(mainAt("/word//main.xml"))],
        [
            "main-final-dot",
            "#962: the same, named by word/main.xml/. (path.posix.join: word/main.xml; RFC 3986: word/main.xml/, no part)",
            () => buildDocx(mainAt("word/main.xml/.")),
        ],
        ["main-absolute-final-dot", "#962: the same, named by /word/main.xml/.", () => buildDocx(mainAt("/word/main.xml/."))],
    ]),
    s70b: withControls("s70b", [
        [
            "notes-plain-calibration",
            "calibration: footnote 1 in word/notes/footnotes.xml, named by the footnotes target notes/footnotes.xml; the body references footnote 1",
            () => buildDocx(notesAt("notes/footnotes.xml")),
        ],
        [
            "notes-empty-segment",
            "#962: the same, named by notes//footnotes.xml (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes//footnotes.xml, no part)",
            () => buildDocx(notesAt("notes//footnotes.xml")),
        ],
        [
            "notes-final-dot",
            "#962: the same, named by notes/footnotes.xml/. (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes/footnotes.xml/, no part)",
            () => buildDocx(notesAt("notes/footnotes.xml/.")),
        ],
    ]),
    // Added after s70a/s70b showed Word refusing a final `/.`: the other spellings whose RFC 3986 path ends in `/`.
    s70c: withControls("s70c", [
        [
            "main-inner-dot-calibration",
            "calibration: the main document stored as word/main.xml, named by word/./main.xml (path.posix.join and RFC 3986 alike: word/main.xml)",
            () => buildDocx(mainAt("word/./main.xml")),
        ],
        [
            "main-final-dotdot",
            "#962: the same, named by word/main.xml/x/.. (path.posix.join: word/main.xml; RFC 3986: word/main.xml/, no part)",
            () => buildDocx(mainAt("word/main.xml/x/..")),
        ],
        [
            "main-trailing-slash",
            "#962: the same, named by word/main.xml/ (path.posix.join and RFC 3986 alike: word/main.xml/, no part)",
            () => buildDocx(mainAt("word/main.xml/")),
        ],
        [
            "notes-final-dotdot",
            "#962: footnote 1 in word/notes/footnotes.xml, named by the footnotes target notes/footnotes.xml/x/.. (path.posix.join: word/notes/footnotes.xml; RFC 3986: word/notes/footnotes.xml/, no part); the body references footnote 1",
            () => buildDocx(notesAt("notes/footnotes.xml/x/..")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-70 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s70a", "s70b", "s70c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s70/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-70 parts of docs/plans/evidence/word-probes-2026-10-24.md into s70/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s70a", "s70b", "s70c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s70/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"main-final-dot.docx", "main-absolute-final-dot.docx", "notes-final-dot.docx", "main-final-dotdot.docx",
           "main-trailing-slash.docx", "notes-final-dotdot.docx"}
ACCEPTED_BY_VALIDATOR = REFUSED - {"main-trailing-slash.docx"}
# The narrative's claims about outcomes, checked against results.json.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning", (file, r)
        assert r["wordValid"] is (file in ACCEPTED_BY_VALIDATOR), (file, r)
        assert r["validatorMatchesWord"] is (file not in ACCEPTED_BY_VALIDATOR), (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 18, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671): the control names sort last, so both
# controls opened after every specimen in every run, and each run opened a row clean after its refused rows.
ORDER = {
    "s70a": ["main-absolute-empty-segment.docx", "main-absolute-final-dot.docx", "main-empty-segment.docx", "main-final-dot.docx",
             "main-plain-calibration.docx", "s70a-control-minimal-end.docx", "s70a-control-minimal.docx"],
    "s70b": ["notes-empty-segment.docx", "notes-final-dot.docx", "notes-plain-calibration.docx", "s70b-control-minimal-end.docx",
             "s70b-control-minimal.docx"],
    "s70c": ["main-final-dotdot.docx", "main-inner-dot-calibration.docx", "main-trailing-slash.docx", "notes-final-dotdot.docx",
             "s70c-control-minimal-end.docx", "s70c-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello", and footnote 1 ("1 Note") after it.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            expected = "Hello1 Note" if file.startswith("notes-") else "Hello"
            assert text == expected, (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
out = [
    f"### Session 70: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The open question of [#962](https://github.com/jandira-tech/docx-validate/issues/962): how Word resolves a "
    "relationship target with an empty segment or a final dot segment. At this revision `relationshipTargetPartName` "
    "resolved a target as `path.posix.join` does, which collapses an empty segment and drops the final `/` that RFC 3986's "
    "remove_dot_segments leaves after a final `.` or `..` segment, so `word/main.xml/.` and `word/main.xml/x/..` named "
    "`word/main.xml`. Three chunks: s70a asks with the `officeDocument` target of a main document stored as `word/main.xml`, "
    "s70b with a `footnotes` target whose note 1 the body references (a note no part defines dangles, and Word offers "
    "recovery for it, session 61), and s70c, added after the first two ran, with the other spellings whose RFC 3986 path ends "
    "in `/`. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: "
    "from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when "
    f"both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in "
    "Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder "
    f"recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, and the control names sort last, so in every run both minimal controls opened "
    "after every specimen, and clean. Each run also opened a row clean after its refused rows: s70a's calibration opened 5th, "
    "after the refused 2nd and 4th; s70b's opened 3rd, after the refused 2nd; and s70c's inner-dot calibration opened 2nd, "
    "between the refused 1st and 3rd. Every clean row's PDF holds the text the specimen stores: `Hello` for the main "
    "document, and `Hello1 Note` (footnote 1) for the notes rows (`pdftotext`, both runs).",
    "",
    "- **An empty segment collapses.** `word//main.xml`, the package-absolute `/word//main.xml`, and the footnotes target "
    "`notes//footnotes.xml` open clean, with the main document and the note rendered, as the plain calibrations do: Word "
    "reads the part through the target, as `path.posix.join` collapses it, where RFC 3986 would keep the empty segment.",
    "- **An inner `.` resolves.** `word/./main.xml` opens clean with the main document rendered.",
    "- **A final `.` or `..` segment leaves a folder.** `word/main.xml/.`, `/word/main.xml/.`, `word/main.xml/x/..`, and "
    "the footnotes targets `notes/footnotes.xml/.` and `notes/footnotes.xml/x/..` get the recovery offer, as "
    "`word/main.xml/` with its trailing `/` does: the RFC 3986 path names a folder, and Word reads no part through it. "
    f"Word-valid at {at} accepts the five final-segment rows, five false negatives from the dropped `/`, and rejects "
    "`word/main.xml/` with `word-main-document-part`.",
    "",
    f"Word resolves a target's dot segments as RFC 3986 does, but collapses an empty segment. Word-valid at {at} matches "
    f"Word on {sum(r['validatorMatchesWord'] for r in results.values())} of {len(rows)} rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 70</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 70 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s70builder.mts", ROOT / "s70builder.mts", "ts"), ("compare.py", ROOT / "s70/compare.py", "python"),
                         ("section.py", ROOT / "s70/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s70/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 71: 22:06Z–22:08Z on 2026-10-27, validator columns at 80fb0996

The open question of [#975](https://github.com/jandira-tech/docx-validate/issues/975): whether Word refuses a relationship target ending in a final `.` or `..` segment for relationship types other than the two session 70 probed (`officeDocument`, `footnotes`). At this revision the read model reads such a target as a folder (#962), but the file-reference walks (`rels-broken`, `rels-target-missing`) resolve a file-system path first, which drops the final `/`, so they find the part. Two chunks: s71a relates `customXml/item1.xml` from the main document's relationships part (session 54 refused that relationship when the part is absent), and s71b names a styles part whose document defaults turn on caps, so the PDF reads `HELLO` only when Word applied it, and a default header holding `Head` that the section references. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 11 of 11 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`80fb0996534e173c461cc91a07f4cc439e94c593`).

The driver opens files in name order. In s71a both minimal controls opened after every specimen, and clean. In s71b they opened 3rd and 4th, clean, after the refused header row, and the styles calibration opened clean 5th, before the refused styles row. Every clean row's PDF holds the text the specimen stores: `Hello` for the controls and the customXml calibration, `HELLO` for the styles calibration, so Word applied its caps, and `Head Hello` for the header calibration (`pdftotext`, both runs).

- **customXml.** `../customXml/item1.xml/.` and `../customXml/item1.xml/x/..` from `word/` get the recovery offer, while `../customXml/item1.xml` beside the same stored part opens clean.
- **styles.** `styles.xml/.` gets the recovery offer, while `styles.xml` opens clean with its caps applied.
- **header.** `header1.xml/.` gets the recovery offer, while `header1.xml` opens clean with `Head` rendered.

Every relationship type probed so far reads a final `.` or `..` segment as RFC 3986 does: the target names a folder, and Word refuses the package. Word-valid at 80fb0996 accepts the four folder rows, four false negatives from the file-reference walks' dropped `/`, and matches Word on 7 of 11 rows.

| Run    | Observed             | Specimen                   | Shape                                                                                                                        | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 80fb0996 | strict at 80fb0996                |
| ------ | -------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | --------------------------------- |
| `s71a` | 22:06:25Z, 22:07:41Z | `s71a-control-minimal`     | control                                                                                                                      | `08a3553f0a83bea4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |
| `s71a` | 22:06:25Z, 22:07:41Z | `customxml-calibration`    | calibration: customXml/item1.xml stored and related from the main document's sidecar by ../customXml/item1.xml               | `11b27716441399b0` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |
| `s71a` | 22:06:25Z, 22:07:41Z | `customxml-final-dot`      | #975: the same, related by ../customXml/item1.xml/. (RFC 3986: customXml/item1.xml/, a folder)                               | `bcd1d5565a0f9588` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                             |
| `s71a` | 22:06:25Z, 22:07:41Z | `customxml-final-dotdot`   | #975: the same, related by ../customXml/item1.xml/x/.. (RFC 3986: customXml/item1.xml/, a folder)                            | `4c967ddf425c6830` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                             |
| `s71a` | 22:06:25Z, 22:07:41Z | `s71a-control-minimal-end` | control                                                                                                                      | `08a3553f0a83bea4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |
| `s71b` | 22:08:20Z, 22:08:58Z | `s71b-control-minimal`     | control                                                                                                                      | `08a3553f0a83bea4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |
| `s71b` | 22:08:20Z, 22:08:58Z | `styles-caps-calibration`  | calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO) | `989e9f490821adaa` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |
| `s71b` | 22:08:20Z, 22:08:58Z | `styles-caps-final-dot`    | #975: the same, named by styles.xml/. (RFC 3986: word/styles.xml/, a folder)                                                 | `85d912bca0e82b78` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                             |
| `s71b` | 22:08:20Z, 22:08:58Z | `header-calibration`       | calibration: a default header word/header1.xml holding Head, referenced from the section, named by header1.xml               | `9424856b4d58d87e` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element` |
| `s71b` | 22:08:20Z, 22:08:58Z | `header-final-dot`         | #975: the same, named by header1.xml/. (RFC 3986: word/header1.xml/, a folder)                                               | `c46448df65dae52b` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `paraid-missing-element` |
| `s71b` | 22:08:20Z, 22:08:58Z | `s71b-control-minimal-end` | control                                                                                                                      | `08a3553f0a83bea4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                             |

<details><summary>Raw records, session 71</summary>

```jsonl
{"run": "s71a", "pass": 1, "name": "s71a-control-minimal", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:06:25+00:00", "staged": "00004__wfv__s71a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71a", "pass": 2, "name": "s71a-control-minimal", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:07:41+00:00", "staged": "00004__wfv__s71a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71a", "pass": 1, "name": "customxml-calibration", "sha256": "11b27716441399b0d8a42e6235b1de65da06a47265d10f7e96d91021810e4129", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:06:25+00:00", "staged": "00000__wfv__customxml-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71a", "pass": 2, "name": "customxml-calibration", "sha256": "11b27716441399b0d8a42e6235b1de65da06a47265d10f7e96d91021810e4129", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:07:41+00:00", "staged": "00000__wfv__customxml-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71a", "pass": 1, "name": "customxml-final-dot", "sha256": "bcd1d5565a0f9588a89bb0c23115eaa6d304e2bca6f1c0d1086fbfc12ec1c771", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:06:25+00:00", "staged": "00001__wfv__customxml-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:05:30.696 'Word found unreadable content in 00001__wfv__customxml-final-dot.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:05:31.532 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00001__wfv__customxml-final-dot.docx)\""]}
{"run": "s71a", "pass": 2, "name": "customxml-final-dot", "sha256": "bcd1d5565a0f9588a89bb0c23115eaa6d304e2bca6f1c0d1086fbfc12ec1c771", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:07:41+00:00", "staged": "00001__wfv__customxml-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:06:49.529 'Word found unreadable content in 00001__wfv__customxml-final-dot.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:06:50.147 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00001__wfv__customxml-final-dot.docx)\""]}
{"run": "s71a", "pass": 1, "name": "customxml-final-dotdot", "sha256": "4c967ddf425c6830237a8ef43c6800cb65fe7cd84cdf11a66e6b245f9b960b09", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:06:25+00:00", "staged": "00002__wfv__customxml-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:06:23.603 Microsoft Word, Word found unreadable content in 00002__wfv__customxml-final-dotdot.docx. Do you wan … t? If you trust the source of this document, click Yes.", "2026-10-27 18:06:24.279 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00002__wfv__customxml-final-dotdot.docx)\""]}
{"run": "s71a", "pass": 2, "name": "customxml-final-dotdot", "sha256": "4c967ddf425c6830237a8ef43c6800cb65fe7cd84cdf11a66e6b245f9b960b09", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:07:41+00:00", "staged": "00002__wfv__customxml-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:07:40.130 Microsoft Word, Word found unreadable content in 00002__wfv__customxml-final-dotdot.docx. Do you wan … t? If you trust the source of this document, click Yes."]}
{"run": "s71a", "pass": 1, "name": "s71a-control-minimal-end", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:06:25+00:00", "staged": "00003__wfv__s71a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71a", "pass": 2, "name": "s71a-control-minimal-end", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:07:41+00:00", "staged": "00003__wfv__s71a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 1, "name": "s71b-control-minimal", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00003__wfv__s71b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 2, "name": "s71b-control-minimal", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00003__wfv__s71b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 1, "name": "styles-caps-calibration", "sha256": "989e9f490821adaa7d550a852d7cb130edbd66dc6918745188e0282329159454", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00004__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 2, "name": "styles-caps-calibration", "sha256": "989e9f490821adaa7d550a852d7cb130edbd66dc6918745188e0282329159454", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00004__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 1, "name": "styles-caps-final-dot", "sha256": "85d912bca0e82b78f5297250756afaa667ecc3174492aecce5be498787c30ef7", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00005__wfv__styles-caps-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:08:20.069 \"Word found unreadable content in 00005__wfv__styles-caps-final-dot.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""]}
{"run": "s71b", "pass": 2, "name": "styles-caps-final-dot", "sha256": "85d912bca0e82b78f5297250756afaa667ecc3174492aecce5be498787c30ef7", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00005__wfv__styles-caps-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:08:58.615 \"Word found unreadable content in 00005__wfv__styles-caps-final-dot.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""]}
{"run": "s71b", "pass": 1, "name": "header-calibration", "sha256": "9424856b4d58d87e2a8f091fea68721a385cb968c28cf6fc835e468d563be17e", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00000__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 2, "name": "header-calibration", "sha256": "9424856b4d58d87e2a8f091fea68721a385cb968c28cf6fc835e468d563be17e", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00000__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 1, "name": "header-final-dot", "sha256": "c46448df65dae52b44bb0e8c30e3c1df5f0b687800ea846d2cd6bb602094c7b3", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00001__wfv__header-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:08:05.530 \"Word found unreadable content in 00001__wfv__header-final-dot.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\""]}
{"run": "s71b", "pass": 2, "name": "header-final-dot", "sha256": "c46448df65dae52b44bb0e8c30e3c1df5f0b687800ea846d2cd6bb602094c7b3", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00001__wfv__header-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:08:41.966 \"Word found unreadable content in 00001__wfv__header-final-dot.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\""]}
{"run": "s71b", "pass": 1, "name": "s71b-control-minimal-end", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:20+00:00", "staged": "00002__wfv__s71b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s71b", "pass": 2, "name": "s71b-control-minimal-end", "sha256": "08a3553f0a83bea41d5b464dbc3650655e71dd73c9dfdf724cf07e5ecd223969", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:08:58+00:00", "staged": "00002__wfv__s71b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s71b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 71 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s71builder.mts`:

```ts
// Session 71 (2026-10-27): does Word read a part through a styles, header or customXml target ending in a final `.` or
// `..` segment (#975)? Session 70 (#962) showed Word refusing such an officeDocument or footnotes target: the RFC 3986
// path names a folder. The file-reference walks (rels-broken) still resolve a file-system path and drop the final `/`.
// s71a: a customXml part stored at customXml/item1.xml, related from the main document's sidecar (session 54 refused the
// absent part); s71b: a styles part whose docDefaults turn on caps, so the PDF reads HELLO when Word applied it and Hello
// when it did not, and a default header holding "Head", named by its target.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s71a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

const CUSTOM_XML = `${XML_DECL}<root xmlns="urn:s71"/>`;
/** The minimal parts with customXml/item1.xml stored and related from the main document's sidecar by `target`. */
const customXmlAt = (target: string): Record<string, string> => ({
    ...P,
    "customXml/item1.xml": CUSTOM_XML,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdX", "customXml", target)),
});
/** The minimal parts with caps turned on in styles.xml's docDefaults, named by the styles target `target`. */
const capsStylesAt = (target: string): Record<string, string> => ({
    ...P,
    "word/styles.xml": replaceOnce(
        P["word/styles.xml"]!,
        "<w:rPrDefault><w:rPr/></w:rPrDefault>",
        "<w:rPrDefault><w:rPr><w:caps/></w:rPr></w:rPrDefault>",
    ),
    [SIDECAR]: replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`),
});
/** The minimal parts with a default header word/header1.xml holding "Head", referenced from the section and named by `target`. */
const headerAt = (target: string): Record<string, string> => ({
    ...P,
    [MAIN]: replaceOnce(
        replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`),
        "<w:sectPr>",
        '<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>',
    ),
    "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Head</w:t></w:r></w:p></w:hdr>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", target)),
    [CT]: overrides(P[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s71a: withControls("s71a", [
        [
            "customxml-calibration",
            "calibration: customXml/item1.xml stored and related from the main document's sidecar by ../customXml/item1.xml",
            () => buildDocx(customXmlAt("../customXml/item1.xml")),
        ],
        [
            "customxml-final-dot",
            "#975: the same, related by ../customXml/item1.xml/. (RFC 3986: customXml/item1.xml/, a folder)",
            () => buildDocx(customXmlAt("../customXml/item1.xml/.")),
        ],
        [
            "customxml-final-dotdot",
            "#975: the same, related by ../customXml/item1.xml/x/.. (RFC 3986: customXml/item1.xml/, a folder)",
            () => buildDocx(customXmlAt("../customXml/item1.xml/x/..")),
        ],
    ]),
    s71b: withControls("s71b", [
        [
            "styles-caps-calibration",
            "calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO)",
            () => buildDocx(capsStylesAt("styles.xml")),
        ],
        [
            "styles-caps-final-dot",
            "#975: the same, named by styles.xml/. (RFC 3986: word/styles.xml/, a folder)",
            () => buildDocx(capsStylesAt("styles.xml/.")),
        ],
        [
            "header-calibration",
            "calibration: a default header word/header1.xml holding Head, referenced from the section, named by header1.xml",
            () => buildDocx(headerAt("header1.xml")),
        ],
        [
            "header-final-dot",
            "#975: the same, named by header1.xml/. (RFC 3986: word/header1.xml/, a folder)",
            () => buildDocx(headerAt("header1.xml/.")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-71 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s71a", "s71b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s71/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-71 parts of docs/plans/evidence/word-probes-2026-10-24.md into s71/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s71a", "s71b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s71/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"customxml-final-dot.docx", "customxml-final-dotdot.docx", "styles-caps-final-dot.docx", "header-final-dot.docx"}
# The narrative's claims about outcomes, checked against results.json: Word refused every folder row and word-valid
# accepted each, and every other row opened clean with word-valid accepting it.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning", (file, r)
        assert r["wordValid"] is True and r["validatorMatchesWord"] is False, (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 11, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order: in
# s71a the control names sort last, after every specimen; in s71b they sort between the header rows and the styles rows.
ORDER = {
    "s71a": ["customxml-calibration.docx", "customxml-final-dot.docx", "customxml-final-dotdot.docx",
             "s71a-control-minimal-end.docx", "s71a-control-minimal.docx"],
    "s71b": ["header-calibration.docx", "header-final-dot.docx", "s71b-control-minimal-end.docx", "s71b-control-minimal.docx",
             "styles-caps-calibration.docx", "styles-caps-final-dot.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello"; "HELLO" when Word applied the caps
# styles part; the header's "Head" before the body.
EXPECTED = {"styles-caps-calibration.docx": "HELLO", "header-calibration.docx": "Head Hello"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            assert text == EXPECTED.get(file, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 71: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The open question of [#975](https://github.com/jandira-tech/docx-validate/issues/975): whether Word refuses a "
    "relationship target ending in a final `.` or `..` segment for relationship types other than the two session 70 "
    "probed (`officeDocument`, `footnotes`). At this revision the read model reads such a target as a folder (#962), but "
    "the file-reference walks (`rels-broken`, `rels-target-missing`) resolve a file-system path first, which drops the "
    "final `/`, so they find the part. Two chunks: s71a relates `customXml/item1.xml` from the main document's "
    "relationships part (session 54 refused that relationship when the part is absent), and s71b names a styles part whose "
    "document defaults turn on caps, so the PDF reads `HELLO` only when Word applied it, and a default header holding "
    "`Head` that the section references. Each chunk ran twice, as two separate driver runs of byte-identical copies, and "
    "each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. "
    "Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is "
    f"the builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order. In s71a both minimal controls opened after every specimen, and clean. In s71b "
    "they opened 3rd and 4th, clean, after the refused header row, and the styles calibration opened clean 5th, before "
    "the refused styles row. Every clean row's PDF holds the text the specimen stores: `Hello` for the controls and the "
    "customXml calibration, `HELLO` for the styles calibration, so Word applied its caps, and `Head Hello` for the header "
    "calibration (`pdftotext`, both runs).",
    "",
    "- **customXml.** `../customXml/item1.xml/.` and `../customXml/item1.xml/x/..` from `word/` get the recovery offer, "
    "while `../customXml/item1.xml` beside the same stored part opens clean.",
    "- **styles.** `styles.xml/.` gets the recovery offer, while `styles.xml` opens clean with its caps applied.",
    "- **header.** `header1.xml/.` gets the recovery offer, while `header1.xml` opens clean with `Head` rendered.",
    "",
    "Every relationship type probed so far reads a final `.` or `..` segment as RFC 3986 does: the target names a folder, "
    f"and Word refuses the package. Word-valid at {at} accepts the four folder rows, four false negatives from the "
    f"file-reference walks' dropped `/`, and matches Word on {matches} of {len(rows)} rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 71</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 71 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s71builder.mts", ROOT / "s71builder.mts", "ts"), ("compare.py", ROOT / "s71/compare.py", "python"),
                         ("section.py", ROOT / "s71/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s71/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 72: 22:16Z–22:20Z on 2026-10-27, validator columns at 80fb0996

The scope question session 71 left for [#975](https://github.com/jandira-tech/docx-validate/issues/975): whether Word refuses a relationship target naming a folder whatever the relationship type, and whether or not anything uses the relationship. Sessions 70 and 71 had refused such a target for `officeDocument`, `footnotes`, `customXml`, `styles` and `header` relationships, each one used. Two chunks: s72a relates an image (`word/media/image1.png`) and a header holding `Head` from the main document's relationships part, and nothing references either; s72b names the core properties part from the package relationships part, and session 71's caps styles part by `styles.xml/`, whose trailing `/` names a folder. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 13 of 13 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`80fb0996534e173c461cc91a07f4cc439e94c593`).

The driver opens files in name order. In s72a both minimal controls opened after every specimen, and clean, and each calibration opened clean right before its refused rows. In s72b the controls opened 3rd and 4th, clean, after the refused core row, and the styles calibration opened clean 5th, before the refused styles row. Every clean row's PDF holds the text the specimen stores: `Hello`, or `HELLO` for the styles calibration, so Word applied its caps (`pdftotext`, both runs). The unused header renders nothing, as no section references it.

- **An unused relationship.** `media/image1.png/.` and `.` (the main document's own folder, `word/`) for the image, and `header1.xml/.` for the header, get the recovery offer, while the plain targets open clean. Nothing references either relationship, so Word refuses the folder target itself, not a part it failed to read.
- **The package relationships part.** `docProps/core.xml/.` gets the recovery offer, while `docProps/core.xml` opens clean.
- **A trailing `/`.** `styles.xml/` gets the recovery offer, while `styles.xml` opens clean with its caps applied.

Every internal relationship target whose RFC 3986 path ends in `/` names a folder, and Word refused each one it was shown, whatever the relationship type and whether anything uses it (sessions 70, 71 and 72). Word-valid at 80fb0996 accepts the five folder rows, five false negatives, and matches Word on 8 of 13 rows.

| Run    | Observed             | Specimen                     | Shape                                                                                                                             | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 80fb0996 | strict at 80fb0996                                                 |
| ------ | -------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | ------------------------------------------------------------------ |
| `s72a` | 22:16:50Z, 22:18:20Z | `s72a-control-minimal`       | control                                                                                                                           | `fdd07a6b2f9014e9` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72a` | 22:16:50Z, 22:18:20Z | `image-unused-calibration`   | calibration: word/media/image1.png stored and related from the main document's sidecar by media/image1.png; nothing references it | `c1d886b01d50e2a4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72a` | 22:16:50Z, 22:18:20Z | `image-unused-final-dot`     | #975: the same, related by media/image1.png/. (RFC 3986: word/media/image1.png/, a folder)                                        | `8ab946c3f667b797` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                                                              |
| `s72a` | 22:16:50Z, 22:18:20Z | `image-unused-dot`           | #975: the same, related by . (RFC 3986: word/, the main document's folder)                                                        | `2bc29ea92ef2c276` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing` |
| `s72a` | 22:16:50Z, 22:18:20Z | `header-unused-calibration`  | calibration: word/header1.xml holding Head, related by header1.xml; no section references it                                      | `add8ade2512c2a01` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element`                                  |
| `s72a` | 22:16:50Z, 22:18:20Z | `header-unused-final-dot`    | #975: the same, related by header1.xml/. (RFC 3986: word/header1.xml/, a folder)                                                  | `43deeb1e4d22308a` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `paraid-missing-element`                                  |
| `s72a` | 22:16:50Z, 22:18:20Z | `s72a-control-minimal-end`   | control                                                                                                                           | `fdd07a6b2f9014e9` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `s72b-control-minimal`       | control                                                                                                                           | `fdd07a6b2f9014e9` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `core-calibration`           | calibration: docProps/core.xml stored and named from the package relationships part by docProps/core.xml                          | `a4ddf7a7859680cc` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `core-final-dot`             | #975: the same, named by docProps/core.xml/. (RFC 3986: docProps/core.xml/, a folder)                                             | `7eb7a2484c020537` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `styles-caps-calibration`    | calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO)      | `99a5268da578b81e` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `styles-caps-trailing-slash` | #975: the same, named by styles.xml/ (a folder)                                                                                   | `a9507d5471b80cf8` | repair-warning | repair-warning | unreadable-content-warning | valid                  | valid                                                              |
| `s72b` | 22:19:35Z, 22:20:06Z | `s72b-control-minimal-end`   | control                                                                                                                           | `fdd07a6b2f9014e9` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                              |

<details><summary>Raw records, session 72</summary>

```jsonl
{"run": "s72a", "pass": 1, "name": "s72a-control-minimal", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00006__wfv__s72a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 2, "name": "s72a-control-minimal", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00006__wfv__s72a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 1, "name": "image-unused-calibration", "sha256": "c1d886b01d50e2a4860f4e5f00762d6080bf200947ad6f04b283e2e722fcba0f", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00002__wfv__image-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF image-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 2, "name": "image-unused-calibration", "sha256": "c1d886b01d50e2a4860f4e5f00762d6080bf200947ad6f04b283e2e722fcba0f", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00002__wfv__image-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF image-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 1, "name": "image-unused-final-dot", "sha256": "8ab946c3f667b797e668bea2dfe7d7ffa7515c342b0615e4a2fc91ace08eab9b", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00004__wfv__image-unused-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:16:49.568 Microsoft Word, Word found unreadable content in 00004__wfv__image-unused-final-dot.docx. Do you wan … t? If you trust the source of this document, click Yes.", "2026-10-27 18:16:50.219 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … y converter. (00004__wfv__image-unused-final-dot.docx)\""]}
{"run": "s72a", "pass": 2, "name": "image-unused-final-dot", "sha256": "8ab946c3f667b797e668bea2dfe7d7ffa7515c342b0615e4a2fc91ace08eab9b", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00004__wfv__image-unused-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:18:19.585 Microsoft Word, Word found unreadable content in 00004__wfv__image-unused-final-dot.docx. Do you wan … t? If you trust the source of this document, click Yes."]}
{"run": "s72a", "pass": 1, "name": "image-unused-dot", "sha256": "2bc29ea92ef2c276e1f0fb7ca513190012c617dde544a6fd3a9e563946a83609", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00003__wfv__image-unused-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:15:59.571 \"Word found unreadable content in 00003__wfv__image-unused-dot.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\""]}
{"run": "s72a", "pass": 2, "name": "image-unused-dot", "sha256": "2bc29ea92ef2c276e1f0fb7ca513190012c617dde544a6fd3a9e563946a83609", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00003__wfv__image-unused-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:17:32.935 \"Word found unreadable content in 00003__wfv__image-unused-dot.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\""]}
{"run": "s72a", "pass": 1, "name": "header-unused-calibration", "sha256": "add8ade2512c2a01259c035df967d7d9ebec238ce871db70bb9bcc3bb5a6367b", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00000__wfv__header-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 2, "name": "header-unused-calibration", "sha256": "add8ade2512c2a01259c035df967d7d9ebec238ce871db70bb9bcc3bb5a6367b", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00000__wfv__header-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 1, "name": "header-unused-final-dot", "sha256": "43deeb1e4d22308a24a55edac7b2ea39ba702b8dced35de428de1a257341db7e", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00001__wfv__header-unused-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:15:42.234 'Word found unreadable content in 00001__wfv__header-unused-final-dot.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:15:43.073 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__header-unused-final-dot.docx)\""]}
{"run": "s72a", "pass": 2, "name": "header-unused-final-dot", "sha256": "43deeb1e4d22308a24a55edac7b2ea39ba702b8dced35de428de1a257341db7e", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00001__wfv__header-unused-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:17:15.819 'Word found unreadable content in 00001__wfv__header-unused-final-dot.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:17:16.441 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__header-unused-final-dot.docx)\""]}
{"run": "s72a", "pass": 1, "name": "s72a-control-minimal-end", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:16:50+00:00", "staged": "00005__wfv__s72a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72a", "pass": 2, "name": "s72a-control-minimal-end", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:18:20+00:00", "staged": "00005__wfv__s72a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 1, "name": "s72b-control-minimal", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00003__wfv__s72b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 2, "name": "s72b-control-minimal", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00003__wfv__s72b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 1, "name": "core-calibration", "sha256": "a4ddf7a7859680ccbc1c8b83e14a7d4e00a4099e965bc3d6d3c0e5d2dd372750", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00000__wfv__core-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF core-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 2, "name": "core-calibration", "sha256": "a4ddf7a7859680ccbc1c8b83e14a7d4e00a4099e965bc3d6d3c0e5d2dd372750", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00000__wfv__core-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF core-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 1, "name": "core-final-dot", "sha256": "7eb7a2484c020537564f2a9f4fba0a8ad23243c6bd18852b219cffa7a6dca8a0", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00001__wfv__core-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:18:45.606 \"Word found unreadable content in 00001__wfv__core-final-dot.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.\""]}
{"run": "s72b", "pass": 2, "name": "core-final-dot", "sha256": "7eb7a2484c020537564f2a9f4fba0a8ad23243c6bd18852b219cffa7a6dca8a0", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00001__wfv__core-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:19:52.711 'Word found unreadable content in 00001__wfv__core-final-dot.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:19:53.507 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00001__wfv__core-final-dot.docx)\""]}
{"run": "s72b", "pass": 1, "name": "styles-caps-calibration", "sha256": "99a5268da578b81e2311eb0cbd69edaac70f779535739f78abddce454f99909c", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00004__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 2, "name": "styles-caps-calibration", "sha256": "99a5268da578b81e2311eb0cbd69edaac70f779535739f78abddce454f99909c", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00004__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 1, "name": "styles-caps-trailing-slash", "sha256": "a9507d5471b80cf845cfecc96a6c5fbb75bc1bf21f80585d469fa062fb893671", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00005__wfv__styles-caps-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:18:59.626 \"Word found unreadable content in 00005__wfv__styles-caps-trailing-slash.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\"", "2026-10-27 18:19:35.392 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00005__wfv__styles-caps-trailing-slas...)'"]}
{"run": "s72b", "pass": 2, "name": "styles-caps-trailing-slash", "sha256": "a9507d5471b80cf845cfecc96a6c5fbb75bc1bf21f80585d469fa062fb893671", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00005__wfv__styles-caps-trailing-slash.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:20:06.104 \"Word found unreadable content in 00005__wfv__styles-caps-trailing-slash.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""]}
{"run": "s72b", "pass": 1, "name": "s72b-control-minimal-end", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:19:35+00:00", "staged": "00002__wfv__s72b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s72b", "pass": 2, "name": "s72b-control-minimal-end", "sha256": "fdd07a6b2f9014e9152a0e290a0d3919a4d359038eeeaa20cb4e0f069fba0371", "validatorRevision": "80fb0996534e173c461cc91a07f4cc439e94c593", "observedAt": "2026-10-27T22:20:06+00:00", "staged": "00002__wfv__s72b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s72b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 72 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s72builder.mts`:

```ts
// Session 72 (2026-10-27): is a relationship target ending in a final `.` or `..` segment, or in `/`, refused whatever
// its type and whether or not anything uses it (#975)? Sessions 70 and 71 refused such a target for officeDocument,
// footnotes, customXml, styles and header relationships, each used. s72a relates an image and a header from the main
// document's sidecar that nothing references, by their plain targets and by folder spellings; s72b names the core
// properties part from the package relationships part, and the caps styles part of session 71 by `styles.xml/`.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s72a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "base64"),
);
/** The minimal parts with word/media/image1.png stored and related from the main document's sidecar by `target`, unused. */
const unusedImageAt = (target: string): Record<string, string | Uint8Array> => ({
    ...P,
    "word/media/image1.png": PNG,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdI", "image", target)),
    [CT]: replaceOnce(P[CT]!, "</Types>", '<Default Extension="png" ContentType="image/png"/></Types>'),
});
/** The minimal parts with a header word/header1.xml holding "Head" related by `target`, which no section references. */
const unusedHeaderAt = (target: string): Record<string, string> => ({
    ...P,
    "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Head</w:t></w:r></w:p></w:hdr>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", target)),
    [CT]: overrides(P[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
});
const CORE_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
const CORE =
    `${XML_DECL}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" ` +
    `xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>S72</dc:title></cp:coreProperties>`;
/** The minimal parts with docProps/core.xml stored and named from the package relationships part by `target`. */
const coreAt = (target: string): Record<string, string> => ({
    ...P,
    "docProps/core.xml": CORE,
    "_rels/.rels": appendRels(P["_rels/.rels"]!, `<Relationship Id="rIdC" Type="${CORE_TYPE}" Target="${target}"/>`),
    [CT]: overrides(P[CT]!, ["docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"]),
});
/** The minimal parts with caps turned on in styles.xml's docDefaults, named by the styles target `target` (session 71's). */
const capsStylesAt = (target: string): Record<string, string> => ({
    ...P,
    "word/styles.xml": replaceOnce(
        P["word/styles.xml"]!,
        "<w:rPrDefault><w:rPr/></w:rPrDefault>",
        "<w:rPrDefault><w:rPr><w:caps/></w:rPr></w:rPrDefault>",
    ),
    [SIDECAR]: replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s72a: withControls("s72a", [
        [
            "image-unused-calibration",
            "calibration: word/media/image1.png stored and related from the main document's sidecar by media/image1.png; nothing references it",
            () => buildDocx(unusedImageAt("media/image1.png")),
        ],
        [
            "image-unused-final-dot",
            "#975: the same, related by media/image1.png/. (RFC 3986: word/media/image1.png/, a folder)",
            () => buildDocx(unusedImageAt("media/image1.png/.")),
        ],
        [
            "image-unused-dot",
            "#975: the same, related by . (RFC 3986: word/, the main document's folder)",
            () => buildDocx(unusedImageAt(".")),
        ],
        [
            "header-unused-calibration",
            "calibration: word/header1.xml holding Head, related by header1.xml; no section references it",
            () => buildDocx(unusedHeaderAt("header1.xml")),
        ],
        [
            "header-unused-final-dot",
            "#975: the same, related by header1.xml/. (RFC 3986: word/header1.xml/, a folder)",
            () => buildDocx(unusedHeaderAt("header1.xml/.")),
        ],
    ]),
    s72b: withControls("s72b", [
        [
            "core-calibration",
            "calibration: docProps/core.xml stored and named from the package relationships part by docProps/core.xml",
            () => buildDocx(coreAt("docProps/core.xml")),
        ],
        [
            "core-final-dot",
            "#975: the same, named by docProps/core.xml/. (RFC 3986: docProps/core.xml/, a folder)",
            () => buildDocx(coreAt("docProps/core.xml/.")),
        ],
        [
            "styles-caps-calibration",
            "calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO)",
            () => buildDocx(capsStylesAt("styles.xml")),
        ],
        ["styles-caps-trailing-slash", "#975: the same, named by styles.xml/ (a folder)", () => buildDocx(capsStylesAt("styles.xml/"))],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-72 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s72a", "s72b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s72/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-72 parts of docs/plans/evidence/word-probes-2026-10-24.md into s72/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s72a", "s72b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s72/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"image-unused-final-dot.docx", "image-unused-dot.docx", "header-unused-final-dot.docx", "core-final-dot.docx",
           "styles-caps-trailing-slash.docx"}
# The narrative's claims about outcomes, checked against results.json: Word refused every folder row and word-valid
# accepted each, and every other row opened clean with word-valid accepting it.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning", (file, r)
        assert r["wordValid"] is True and r["validatorMatchesWord"] is False, (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 13, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order: in
# s72a the control names sort last, after every specimen; in s72b they sort between the core rows and the styles rows.
ORDER = {
    "s72a": ["header-unused-calibration.docx", "header-unused-final-dot.docx", "image-unused-calibration.docx",
             "image-unused-dot.docx", "image-unused-final-dot.docx", "s72a-control-minimal-end.docx", "s72a-control-minimal.docx"],
    "s72b": ["core-calibration.docx", "core-final-dot.docx", "s72b-control-minimal-end.docx", "s72b-control-minimal.docx",
             "styles-caps-calibration.docx", "styles-caps-trailing-slash.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello", and "HELLO" when Word applied the caps
# styles part. The unused header renders nothing, as no section references it.
EXPECTED = {"styles-caps-calibration.docx": "HELLO"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            assert text == EXPECTED.get(file, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 72: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The scope question session 71 left for [#975](https://github.com/jandira-tech/docx-validate/issues/975): whether Word "
    "refuses a relationship target naming a folder whatever the relationship type, and whether or not anything uses the "
    "relationship. Sessions 70 and 71 had refused such a target for `officeDocument`, `footnotes`, `customXml`, `styles` "
    "and `header` relationships, each one used. Two chunks: s72a relates an image (`word/media/image1.png`) and a header "
    "holding `Head` from the main document's relationships part, and nothing references either; s72b names the core "
    "properties part from the package relationships part, and session 71's caps styles part by `styles.xml/`, whose "
    "trailing `/` names a folder. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    f"is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} "
    "rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description "
    f"of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order. In s72a both minimal controls opened after every specimen, and clean, and each "
    "calibration opened clean right before its refused rows. In s72b the controls opened 3rd and 4th, clean, after the "
    "refused core row, and the styles calibration opened clean 5th, before the refused styles row. Every clean row's PDF "
    "holds the text the specimen stores: `Hello`, or `HELLO` for the styles calibration, so Word applied its caps "
    "(`pdftotext`, both runs). The unused header renders nothing, as no section references it.",
    "",
    "- **An unused relationship.** `media/image1.png/.` and `.` (the main document's own folder, `word/`) for the image, "
    "and `header1.xml/.` for the header, get the recovery offer, while the plain targets open clean. Nothing references "
    "either relationship, so Word refuses the folder target itself, not a part it failed to read.",
    "- **The package relationships part.** `docProps/core.xml/.` gets the recovery offer, while `docProps/core.xml` "
    "opens clean.",
    "- **A trailing `/`.** `styles.xml/` gets the recovery offer, while `styles.xml` opens clean with its caps applied.",
    "",
    "Every internal relationship target whose RFC 3986 path ends in `/` names a folder, and Word refused each one it was "
    "shown, whatever the relationship type and whether anything uses it (sessions 70, 71 and 72). "
    f"Word-valid at {at} accepts the five folder rows, five false negatives, and matches Word on {matches} of {len(rows)} rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 72</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 72 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s72builder.mts", ROOT / "s72builder.mts", "ts"), ("compare.py", ROOT / "s72/compare.py", "python"),
                         ("section.py", ROOT / "s72/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s72/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 73: 22:43Z–22:45Z on 2026-10-27, validator columns at e493c719

The rest of [#975](https://github.com/jandira-tech/docx-validate/issues/975)'s own probe matrix, which CodeRabbit asked for on [#978](https://github.com/jandira-tech/docx-validate/pull/978): sessions 71 and 72 probed `/x/..` only for `customXml`, and no `settings` relationship. One chunk: s73a relates a settings part by `settings.xml`, `settings.xml/.` and `settings.xml/x/..`, and names session 71's caps styles part and its used header by `styles.xml/x/..` and `header1.xml/x/..`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 9 of 9 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder ran at the revision that fixes #975 and recorded it in every row (`e493c71943fc02fe851cf72e578faaa141114ca1`), so the validator columns are a prediction this session tests.

The driver opens files in name order, so the minimal controls opened 3rd and 4th, clean, after the refused header row and before the settings rows, and each calibration opened clean right before its refused rows. Every clean row's PDF holds the text the specimen stores: `Hello`, `HELLO` for the styles calibration, so Word applied its caps, and `Head Hello` for the header calibration (`pdftotext`, both runs).

- **settings.** `settings.xml/.` and `settings.xml/x/..` get the recovery offer, while `settings.xml` opens clean.
- **`/x/..` for styles and a used header.** `styles.xml/x/..` and `header1.xml/x/..` get the recovery offer, as their `/.` twins did in session 71.

With sessions 70, 71 and 72, Word refused a target naming a folder for every relationship type and spelling it was shown. Word-valid at e493c719 rejects the four folder rows with `rels-broken` and matches Word on 9 of 9 rows.

| Run    | Observed             | Specimen                   | Shape                                                                                                                        | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at e493c719 | strict at e493c719                                                                           |
| ------ | -------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | -------------------------------------------------------------------------------------------- |
| `s73a` | 22:43:59Z, 22:45:59Z | `s73a-control-minimal`     | control                                                                                                                      | `a97b185e182690e7` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                        |
| `s73a` | 22:43:59Z, 22:45:59Z | `settings-calibration`     | calibration: word/settings.xml stored and related from the main document's sidecar by settings.xml                           | `e278012806e68db2` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                        |
| `s73a` | 22:43:59Z, 22:45:59Z | `settings-final-dot`       | #975: the same, related by settings.xml/. (RFC 3986: word/settings.xml/, a folder)                                           | `a76a3fd8c2fd8490` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s73a` | 22:43:59Z, 22:45:59Z | `settings-final-dotdot`    | #975: the same, related by settings.xml/x/.. (RFC 3986: word/settings.xml/, a folder)                                        | `3c1a932de2f4b948` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s73a` | 22:43:59Z, 22:45:59Z | `styles-caps-calibration`  | calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO) | `b06349ad7b76ad3b` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                        |
| `s73a` | 22:43:59Z, 22:45:59Z | `styles-caps-final-dotdot` | #975: the same, named by styles.xml/x/.. (RFC 3986: word/styles.xml/, a folder)                                              | `d0772e29a976046e` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s73a` | 22:43:59Z, 22:45:59Z | `header-calibration`       | calibration: a default header word/header1.xml holding Head, referenced from the section, named by header1.xml               | `1d39b2f3ae361b13` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `paraid-missing-element`                                                            |
| `s73a` | 22:43:59Z, 22:45:59Z | `header-final-dotdot`      | #975: the same, named by header1.xml/x/.. (RFC 3986: word/header1.xml/, a folder)                                            | `a541b769acd69e81` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s73a` | 22:43:59Z, 22:45:59Z | `s73a-control-minimal-end` | control                                                                                                                      | `a97b185e182690e7` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                        |

<details><summary>Raw records, session 73</summary>

```jsonl
{"run": "s73a", "pass": 1, "name": "s73a-control-minimal", "sha256": "a97b185e182690e70da45f48bafdf01a528cdc4156509346905578f47e1dd5f8", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00003__wfv__s73a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s73a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 2, "name": "s73a-control-minimal", "sha256": "a97b185e182690e70da45f48bafdf01a528cdc4156509346905578f47e1dd5f8", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00003__wfv__s73a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s73a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 1, "name": "settings-calibration", "sha256": "e278012806e68db2cb54aa1f6b5aedc378ec7261b11336b77133b62d39707444", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00004__wfv__settings-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 2, "name": "settings-calibration", "sha256": "e278012806e68db2cb54aa1f6b5aedc378ec7261b11336b77133b62d39707444", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00004__wfv__settings-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 1, "name": "settings-final-dot", "sha256": "a76a3fd8c2fd84909049f3a69e6b2f7c1607a7813bfa77928605680993e5c803", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00005__wfv__settings-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:43:05.424 \"Word found unreadable content in 00005__wfv__settings-final-dot.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\""]}
{"run": "s73a", "pass": 2, "name": "settings-final-dot", "sha256": "a76a3fd8c2fd84909049f3a69e6b2f7c1607a7813bfa77928605680993e5c803", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00005__wfv__settings-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:44:48.377 \"Word found unreadable content in 00005__wfv__settings-final-dot.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\""]}
{"run": "s73a", "pass": 1, "name": "settings-final-dotdot", "sha256": "3c1a932de2f4b948183377273648f9d9ceb71d996518168a949308ca57abbce2", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00006__wfv__settings-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:43:48.125 Microsoft Word, Word found unreadable content in 00006__wfv__settings-final-dotdot.docx. Do you want … t? If you trust the source of this document, click Yes."]}
{"run": "s73a", "pass": 2, "name": "settings-final-dotdot", "sha256": "3c1a932de2f4b948183377273648f9d9ceb71d996518168a949308ca57abbce2", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00006__wfv__settings-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:45:38.213 Microsoft Word, Word found unreadable content in 00006__wfv__settings-final-dotdot.docx. Do you want … t? If you trust the source of this document, click Yes.", "2026-10-27 18:45:39.686 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__settings-final-dotdot.docx)\""]}
{"run": "s73a", "pass": 1, "name": "styles-caps-calibration", "sha256": "b06349ad7b76ad3ba8d8552ccf197e4359b767bc240c5c448fba335540403ff7", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00007__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 2, "name": "styles-caps-calibration", "sha256": "b06349ad7b76ad3ba8d8552ccf197e4359b767bc240c5c448fba335540403ff7", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00007__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 1, "name": "styles-caps-final-dotdot", "sha256": "d0772e29a976046e08e21c4a044ac34474bfacc1d610d5852ef29fa11383e245", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00008__wfv__styles-caps-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:43:59.065 \"Word found unreadable content in 00008__wfv__styles-caps-final-dotdot.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\"", "2026-10-27 18:43:59.065 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00008__wfv__styles-caps-final-dotdot....)\""]}
{"run": "s73a", "pass": 2, "name": "styles-caps-final-dotdot", "sha256": "d0772e29a976046e08e21c4a044ac34474bfacc1d610d5852ef29fa11383e245", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00008__wfv__styles-caps-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:45:59.783 \"Word found unreadable content in 00008__wfv__styles-caps-final-dotdot.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.\""]}
{"run": "s73a", "pass": 1, "name": "header-calibration", "sha256": "1d39b2f3ae361b13c7b4791ec08272a1f11f2f42f74e98212af1391c6684bd18", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00000__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 2, "name": "header-calibration", "sha256": "1d39b2f3ae361b13c7b4791ec08272a1f11f2f42f74e98212af1391c6684bd18", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00000__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 1, "name": "header-final-dotdot", "sha256": "a541b769acd69e8114e84d91067a40d25f7c3b2f85d0322ccb276eca649c9569", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00001__wfv__header-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:42:45.609 'Word found unreadable content in 00001__wfv__header-final-dotdot.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:42:46.547 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00001__wfv__header-final-dotdot.docx)\""]}
{"run": "s73a", "pass": 2, "name": "header-final-dotdot", "sha256": "a541b769acd69e8114e84d91067a40d25f7c3b2f85d0322ccb276eca649c9569", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00001__wfv__header-final-dotdot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 18:44:30.826 'Word found unreadable content in 00001__wfv__header-final-dotdot.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-27 18:44:31.529 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00001__wfv__header-final-dotdot.docx)\""]}
{"run": "s73a", "pass": 1, "name": "s73a-control-minimal-end", "sha256": "a97b185e182690e70da45f48bafdf01a528cdc4156509346905578f47e1dd5f8", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:43:59+00:00", "staged": "00002__wfv__s73a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s73a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s73a", "pass": 2, "name": "s73a-control-minimal-end", "sha256": "a97b185e182690e70da45f48bafdf01a528cdc4156509346905578f47e1dd5f8", "validatorRevision": "e493c71943fc02fe851cf72e578faaa141114ca1", "observedAt": "2026-10-27T22:45:59+00:00", "staged": "00002__wfv__s73a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s73a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 73 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s73builder.mts`:

```ts
// Session 73 (2026-10-27): the rest of #975's own probe matrix, which CodeRabbit asked for on #978. Sessions 71 and 72
// refused a folder target for customXml, styles, header (used and unused), image and core-properties relationships, but
// probed `/x/..` only for customXml and never a settings relationship. s73a relates a settings part by its plain target,
// by `settings.xml/.` and by `settings.xml/x/..`, and names session 71's caps styles part and its used header by
// `styles.xml/x/..` and `header1.xml/x/..`.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s73a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The minimal parts with word/settings.xml stored and related from the main document's sidecar by `target`. */
const settingsAt = (target: string): Record<string, string> => ({
    ...P,
    "word/settings.xml": `${XML_DECL}<w:settings xmlns:w="${W}"><w:zoom w:percent="100"/></w:settings>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdS", "settings", target)),
    [CT]: overrides(P[CT]!, ["word/settings.xml", `${WML}.settings+xml`]),
});
/** The minimal parts with caps turned on in styles.xml's docDefaults, named by the styles target `target`. */
const capsStylesAt = (target: string): Record<string, string> => ({
    ...P,
    "word/styles.xml": replaceOnce(
        P["word/styles.xml"]!,
        "<w:rPrDefault><w:rPr/></w:rPrDefault>",
        "<w:rPrDefault><w:rPr><w:caps/></w:rPr></w:rPrDefault>",
    ),
    [SIDECAR]: replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`),
});
/** The minimal parts with a default header word/header1.xml holding "Head", referenced from the section and named by `target`. */
const headerAt = (target: string): Record<string, string> => ({
    ...P,
    [MAIN]: replaceOnce(
        replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`),
        "<w:sectPr>",
        '<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>',
    ),
    "word/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Head</w:t></w:r></w:p></w:hdr>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", target)),
    [CT]: overrides(P[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s73a: withControls("s73a", [
        [
            "settings-calibration",
            "calibration: word/settings.xml stored and related from the main document's sidecar by settings.xml",
            () => buildDocx(settingsAt("settings.xml")),
        ],
        [
            "settings-final-dot",
            "#975: the same, related by settings.xml/. (RFC 3986: word/settings.xml/, a folder)",
            () => buildDocx(settingsAt("settings.xml/.")),
        ],
        [
            "settings-final-dotdot",
            "#975: the same, related by settings.xml/x/.. (RFC 3986: word/settings.xml/, a folder)",
            () => buildDocx(settingsAt("settings.xml/x/..")),
        ],
        [
            "styles-caps-calibration",
            "calibration: styles.xml's docDefaults turn on caps; the styles target is styles.xml (Word applied it if the PDF reads HELLO)",
            () => buildDocx(capsStylesAt("styles.xml")),
        ],
        [
            "styles-caps-final-dotdot",
            "#975: the same, named by styles.xml/x/.. (RFC 3986: word/styles.xml/, a folder)",
            () => buildDocx(capsStylesAt("styles.xml/x/..")),
        ],
        [
            "header-calibration",
            "calibration: a default header word/header1.xml holding Head, referenced from the section, named by header1.xml",
            () => buildDocx(headerAt("header1.xml")),
        ],
        [
            "header-final-dotdot",
            "#975: the same, named by header1.xml/x/.. (RFC 3986: word/header1.xml/, a folder)",
            () => buildDocx(headerAt("header1.xml/x/..")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-73 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s73a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s73/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-73 parts of docs/plans/evidence/word-probes-2026-10-24.md into s73/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s73a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s73/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"settings-final-dot.docx", "settings-final-dotdot.docx", "styles-caps-final-dotdot.docx", "header-final-dotdot.docx"}
# The narrative's claims about outcomes, checked against results.json: Word refused every folder row and word-valid,
# built at the fixing revision, rejected each; every other row opened clean with word-valid accepting it.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning", (file, r)
        assert r["wordValid"] is False and r["validatorMatchesWord"] is True, (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 9, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the controls opened 3rd and 4th, between the header rows and the settings rows.
ORDER = {
    "s73a": ["header-calibration.docx", "header-final-dotdot.docx", "s73a-control-minimal-end.docx", "s73a-control-minimal.docx",
             "settings-calibration.docx", "settings-final-dot.docx", "settings-final-dotdot.docx", "styles-caps-calibration.docx",
             "styles-caps-final-dotdot.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello", "HELLO" when Word applied the caps
# styles part, and the used header's "Head" before the body.
EXPECTED = {"styles-caps-calibration.docx": "HELLO", "header-calibration.docx": "Head Hello"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            assert text == EXPECTED.get(file, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 73: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The rest of [#975](https://github.com/jandira-tech/docx-validate/issues/975)'s own probe matrix, which CodeRabbit "
    "asked for on [#978](https://github.com/jandira-tech/docx-validate/pull/978): sessions 71 and 72 probed `/x/..` only "
    "for `customXml`, and no `settings` relationship. One chunk: s73a relates a settings part by `settings.xml`, "
    "`settings.xml/.` and `settings.xml/x/..`, and names session 71's caps styles part and its used header by "
    "`styles.xml/x/..` and `header1.xml/x/..`. It ran twice, as two separate driver runs of byte-identical copies, and "
    "each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. "
    f"Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of "
    f"{len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's "
    f"description of the specimen. The builder ran at the revision that fixes #975 and recorded it in every row (`{rev}`), "
    "so the validator columns are a prediction this session tests.",
    "",
    "The driver opens files in name order, so the minimal controls opened 3rd and 4th, clean, after the refused header "
    "row and before the settings rows, and each calibration opened clean right before its refused rows. Every clean "
    "row's PDF holds the text the specimen stores: `Hello`, `HELLO` for the styles calibration, so Word applied its caps, "
    "and `Head Hello` for the header calibration (`pdftotext`, both runs).",
    "",
    "- **settings.** `settings.xml/.` and `settings.xml/x/..` get the recovery offer, while `settings.xml` opens clean.",
    "- **`/x/..` for styles and a used header.** `styles.xml/x/..` and `header1.xml/x/..` get the recovery offer, as "
    "their `/.` twins did in session 71.",
    "",
    "With sessions 70, 71 and 72, Word refused a target naming a folder for every relationship type and spelling it was "
    f"shown. Word-valid at {at} rejects the four folder rows with `rels-broken` and matches Word on {matches} of "
    f"{len(rows)} rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 73</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 73 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s73builder.mts", ROOT / "s73builder.mts", "ts"), ("compare.py", ROOT / "s73/compare.py", "python"),
                         ("section.py", ROOT / "s73/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s73/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 74: 23:07Z–23:07Z on 2026-10-27, validator columns at 37a94dd4

A package-absolute notes target that climbs above the package root. [#947](https://github.com/jandira-tech/docx-validate/issues/947) made the resolvers stop a package-absolute target's `..` segments at the root, as sessions 63 and 64 showed Word stopping a relative climb, so `/../footnotes.xml` reads the note at `/footnotes.xml`; no session had shown Word such a target. One chunk: s74a names a footnotes part, which holds footnote 1 that the body references, by `/footnotes.xml`, `/../footnotes.xml`, `/../../footnotes.xml` and `/../word/footnotes.xml`, names it by `/../footnotes.xml` with the note only in `word/footnotes.xml`, names an endnotes part by `/../endnotes.xml`, and repeats session 64's relative `../../footnotes.xml`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 9 of 9 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`37a94dd493d2d3376e4c0baecb70a586e4d3365f`), so the validator columns are a prediction this session tests.

The driver opens files in name order, so the minimal controls were queued last and opened clean. Every clean notes row's PDF holds `Hello`, the note's mark (`1` for a footnote, `i` for an endnote) and `Note text`, so Word read the note from the part the climb stops at, and the controls hold `Hello` (`pdftotext`, both runs).

- **A package-absolute climb stops at the root.** `/../footnotes.xml` and `/../../footnotes.xml` with the note in `/footnotes.xml`, `/../word/footnotes.xml` with it in `word/footnotes.xml`, and the endnotes twin `/../endnotes.xml` open clean and render the note, as `/footnotes.xml` and the relative `../../footnotes.xml` do.
- **The climb names the root's part, not the source folder's.** `/../footnotes.xml` with the note only in `word/footnotes.xml` gets the recovery offer: the reference dangles, as session 64's relative climb did with the note in `word/`.

Word-valid at 37a94dd4 accepts every clean row and rejects the refused one with `word-footnote-reference-missing`, matching Word on 9 of 9 rows. Strict reports `rels-broken` for each climb, as it did before #947.

| Run    | Observed             | Specimen                                                | Shape                                                                                                                                    | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 37a94dd4                     | strict at 37a94dd4                                                                                                              |
| ------ | -------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `s74a` | 23:07:12Z, 23:07:38Z | `s74a-control-minimal`                                  | control                                                                                                                                  | `87bd9294f06a8638` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-absolute-at-root-calibration`                | calibration: the only footnotes relationship targets /footnotes.xml (package-absolute, no climb); footnote 1 sits in /footnotes.xml      | `a8c07c196f1cfd64` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                                                               |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-absolute-climb-one-note-at-root`             | #947: the only footnotes relationship targets /../footnotes.xml; footnote 1 sits in /footnotes.xml (stopped at the root: /footnotes.xml) | `a887441bd2989a23` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                    |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-absolute-climb-two-note-at-root`             | #947: the only footnotes relationship targets /../../footnotes.xml; footnote 1 sits in /footnotes.xml                                    | `6d0702930ad6199f` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                    |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-absolute-climb-one-note-in-word-folder`      | #947: the only footnotes relationship targets /../footnotes.xml; footnote 1 sits only in word/footnotes.xml (no /footnotes.xml)          | `1d84992d54c1db97` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-footnote-reference-missing` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`, `word-footnote-reference-missing` |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-absolute-climb-into-word-folder`             | #947: the only footnotes relationship targets /../word/footnotes.xml; footnote 1 sits in word/footnotes.xml                              | `15a1c4e7565655b9` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                    |
| `s74a` | 23:07:12Z, 23:07:38Z | `endnotes-absolute-climb-one-note-at-root`              | #947 endnotes twin: the only endnotes relationship targets /../endnotes.xml; endnote 1 sits in /endnotes.xml                             | `f560f08f17ec39c8` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                    |
| `s74a` | 23:07:12Z, 23:07:38Z | `footnotes-relative-climb-two-note-at-root-calibration` | calibration, repeat of s64a: the only footnotes relationship targets ../../footnotes.xml from word/; footnote 1 sits in /footnotes.xml   | `3ba73f90655a7d66` | clean-open     | clean-open     | clean-open                 | valid                                      | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing`                                    |
| `s74a` | 23:07:12Z, 23:07:38Z | `s74a-control-minimal-end`                              | control                                                                                                                                  | `87bd9294f06a8638` | clean-open     | clean-open     | clean-open                 | valid                                      | valid                                                                                                                           |

<details><summary>Raw records, session 74</summary>

```jsonl
{"run": "s74a", "pass": 1, "name": "s74a-control-minimal", "sha256": "87bd9294f06a86384a524fc88ce8c8c6209e83b5bcc20f4bb388a6a235272667", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00008__wfv__s74a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s74a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "s74a-control-minimal", "sha256": "87bd9294f06a86384a524fc88ce8c8c6209e83b5bcc20f4bb388a6a235272667", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00008__wfv__s74a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s74a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "footnotes-absolute-at-root-calibration", "sha256": "a8c07c196f1cfd64d92dd7219d21279f4ef55c3334b951855f03cf1f46ccad2f", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00001__wfv__footnotes-absolute-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-at-root-calibration_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "footnotes-absolute-at-root-calibration", "sha256": "a8c07c196f1cfd64d92dd7219d21279f4ef55c3334b951855f03cf1f46ccad2f", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00001__wfv__footnotes-absolute-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-at-root-calibration_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "footnotes-absolute-climb-one-note-at-root", "sha256": "a887441bd2989a23c8123691cae027548c39307c037e465fa5642c53ef732c8d", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00003__wfv__footnotes-absolute-climb-one-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-one-note-at-root_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "footnotes-absolute-climb-one-note-at-root", "sha256": "a887441bd2989a23c8123691cae027548c39307c037e465fa5642c53ef732c8d", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00003__wfv__footnotes-absolute-climb-one-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-one-note-at-root_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "footnotes-absolute-climb-two-note-at-root", "sha256": "6d0702930ad6199fb445e640bfb2ee175774d974ea4a359dcf88d0b88cb814df", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00005__wfv__footnotes-absolute-climb-two-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-two-note-at-root_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "footnotes-absolute-climb-two-note-at-root", "sha256": "6d0702930ad6199fb445e640bfb2ee175774d974ea4a359dcf88d0b88cb814df", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00005__wfv__footnotes-absolute-climb-two-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-two-note-at-root_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "footnotes-absolute-climb-one-note-in-word-folder", "sha256": "1d84992d54c1db97dde28a8b7676a418b15263b1eae569575293c6c8206625a4", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00004__wfv__footnotes-absolute-climb-one-note-in-word-folder.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 19:06:59.480 'Word found unreadable content in 00004__wfv__footnotes-absolute-climb-one-note-in-word-folder.... D … ? If you trust the source of this document, click Yes.'", "2026-10-27 19:07:00.087 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__footnotes-absolute-climb-...)\""]}
{"run": "s74a", "pass": 2, "name": "footnotes-absolute-climb-one-note-in-word-folder", "sha256": "1d84992d54c1db97dde28a8b7676a418b15263b1eae569575293c6c8206625a4", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00004__wfv__footnotes-absolute-climb-one-note-in-word-folder.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 19:07:26.881 'Word found unreadable content in 00004__wfv__footnotes-absolute-climb-one-note-in-word-folder.... D … ? If you trust the source of this document, click Yes.'", "2026-10-27 19:07:27.508 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__footnotes-absolute-climb-...)\""]}
{"run": "s74a", "pass": 1, "name": "footnotes-absolute-climb-into-word-folder", "sha256": "15a1c4e7565655b94e60d48b6a256866648d1da990c6070f5ad4218ed2da0d73", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00002__wfv__footnotes-absolute-climb-into-word-folder.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-into-word-folder_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "footnotes-absolute-climb-into-word-folder", "sha256": "15a1c4e7565655b94e60d48b6a256866648d1da990c6070f5ad4218ed2da0d73", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00002__wfv__footnotes-absolute-climb-into-word-folder.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-absolute-climb-into-word-folder_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "endnotes-absolute-climb-one-note-at-root", "sha256": "f560f08f17ec39c888f2e83ab82a03a68b9c5d4f1ef396b1570680e3574e21ff", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00000__wfv__endnotes-absolute-climb-one-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-absolute-climb-one-note-at-root_byword.pdf (15959 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "endnotes-absolute-climb-one-note-at-root", "sha256": "f560f08f17ec39c888f2e83ab82a03a68b9c5d4f1ef396b1570680e3574e21ff", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00000__wfv__endnotes-absolute-climb-one-note-at-root.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-absolute-climb-one-note-at-root_byword.pdf (15959 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "footnotes-relative-climb-two-note-at-root-calibration", "sha256": "3ba73f90655a7d6623975410cdfc3a2149e98189dea57c33390947a934b59f87", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00006__wfv__footnotes-relative-climb-two-note-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-relative-climb-two-note-at-root-calibration_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "footnotes-relative-climb-two-note-at-root-calibration", "sha256": "3ba73f90655a7d6623975410cdfc3a2149e98189dea57c33390947a934b59f87", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00006__wfv__footnotes-relative-climb-two-note-at-root-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-relative-climb-two-note-at-root-calibration_byword.pdf (15684 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 1, "name": "s74a-control-minimal-end", "sha256": "87bd9294f06a86384a524fc88ce8c8c6209e83b5bcc20f4bb388a6a235272667", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:12+00:00", "staged": "00007__wfv__s74a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s74a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s74a", "pass": 2, "name": "s74a-control-minimal-end", "sha256": "87bd9294f06a86384a524fc88ce8c8c6209e83b5bcc20f4bb388a6a235272667", "validatorRevision": "37a94dd493d2d3376e4c0baecb70a586e4d3365f", "observedAt": "2026-10-27T23:07:38+00:00", "staged": "00007__wfv__s74a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s74a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 74 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s74builder.mts`:

```ts
// Session 74 (2026-10-27): a package-absolute notes target that climbs above the root. #947 made the resolvers stop a
// package-absolute target's `..` segments at the package root, so `/../footnotes.xml` reads the note at /footnotes.xml,
// and CLAUDE.md note 27 says Word has not been probed with such a target (session 70 showed Word reading a
// package-absolute officeDocument target from the root; sessions 63 and 64 showed it stopping a relative climb there).
// s74a: footnotes targets `/footnotes.xml`, `/../footnotes.xml`, `/../../footnotes.xml` and `/../word/footnotes.xml`,
// the climb with the note only in word/footnotes.xml, the endnotes twin, and session 64's relative climb repeated.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's,
// the notes helpers s64builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s74a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
const TEXT_P = "<w:p><w:r><w:t>Note text</w:t></w:r></w:p>";

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

type Kind = "footnote" | "endnote";
const notesXml = (kind: Kind, held: string) =>
    `${XML_DECL}<w:${kind}s xmlns:w="${W}"><w:${kind} w:id="${held}">${TEXT_P}</w:${kind}></w:${kind}s>`;
const noteRef = (kind: Kind, id: string) => `<w:r><w:${kind}Reference w:id="${id}"/></w:r>`;
/** `parts` with `run` appended inside the main document's only paragraph. */
const mainWith = (parts: Record<string, string>, run: string): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(parts[MAIN]!, "</w:r></w:p>", `</w:r>${run}</w:p>`),
});
/** Note 1 of `kind` stored at `stored`, typed as `kind`s, named only by a `<kind>s` relationship with `target`; the body references it. */
const notesAt = (kind: Kind, stored: string, target: string) =>
    buildDocx(
        mainWith(
            {
                ...P,
                [stored]: notesXml(kind, "1"),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", `${kind}s`, target)),
                [CT]: overrides(P[CT]!, [stored, `${WML}.${kind}s+xml`]),
            },
            noteRef(kind, "1"),
        ),
    );

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s74a: withControls("s74a", [
        [
            "footnotes-absolute-at-root-calibration",
            "calibration: the only footnotes relationship targets /footnotes.xml (package-absolute, no climb); footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", "/footnotes.xml"),
        ],
        [
            "footnotes-absolute-climb-one-note-at-root",
            "#947: the only footnotes relationship targets /../footnotes.xml; footnote 1 sits in /footnotes.xml (stopped at the root: /footnotes.xml)",
            () => notesAt("footnote", "footnotes.xml", "/../footnotes.xml"),
        ],
        [
            "footnotes-absolute-climb-two-note-at-root",
            "#947: the only footnotes relationship targets /../../footnotes.xml; footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", "/../../footnotes.xml"),
        ],
        [
            "footnotes-absolute-climb-one-note-in-word-folder",
            "#947: the only footnotes relationship targets /../footnotes.xml; footnote 1 sits only in word/footnotes.xml (no /footnotes.xml)",
            () => notesAt("footnote", "word/footnotes.xml", "/../footnotes.xml"),
        ],
        [
            "footnotes-absolute-climb-into-word-folder",
            "#947: the only footnotes relationship targets /../word/footnotes.xml; footnote 1 sits in word/footnotes.xml",
            () => notesAt("footnote", "word/footnotes.xml", "/../word/footnotes.xml"),
        ],
        [
            "endnotes-absolute-climb-one-note-at-root",
            "#947 endnotes twin: the only endnotes relationship targets /../endnotes.xml; endnote 1 sits in /endnotes.xml",
            () => notesAt("endnote", "endnotes.xml", "/../endnotes.xml"),
        ],
        [
            "footnotes-relative-climb-two-note-at-root-calibration",
            "calibration, repeat of s64a: the only footnotes relationship targets ../../footnotes.xml from word/; footnote 1 sits in /footnotes.xml",
            () => notesAt("footnote", "footnotes.xml", "../../footnotes.xml"),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-74 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s74a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": (all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True)})
(ROOT / "s74/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-74 parts of docs/plans/evidence/word-probes-2026-10-24.md into s74/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s74a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s74/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"footnotes-absolute-climb-one-note-in-word-folder.docx"}
# The narrative's claims about outcomes, checked against results.json: Word refused the climb whose note sits only in
# word/ and word-valid rejected it; every other row opened clean with word-valid accepting it.
for (label, file), r in results.items():
    if file in REFUSED:
        assert r["outcome"] == "unreadable-content-warning", (file, r)
        assert r["wordValid"] is False and r["validatorMatchesWord"] is True, (file, r)
    else:
        assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 9, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the endnotes row opened first and the controls last.
ORDER = {
    "s74a": ["endnotes-absolute-climb-one-note-at-root.docx", "footnotes-absolute-at-root-calibration.docx",
             "footnotes-absolute-climb-into-word-folder.docx", "footnotes-absolute-climb-one-note-at-root.docx",
             "footnotes-absolute-climb-one-note-in-word-folder.docx", "footnotes-absolute-climb-two-note-at-root.docx",
             "footnotes-relative-climb-two-note-at-root-calibration.docx", "s74a-control-minimal-end.docx",
             "s74a-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello", then the note's mark and its text,
# "1" for a footnote and "i" for an endnote, so Word read the note part the target names; the controls hold "Hello" only.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            expected = "Hello" if "control" in file else ("Helloi Note text" if file.startswith("endnotes") else "Hello1 Note text")
            assert text == expected, (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 74: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "A package-absolute notes target that climbs above the package root. "
    "[#947](https://github.com/jandira-tech/docx-validate/issues/947) made the resolvers stop a package-absolute target's "
    "`..` segments at the root, as sessions 63 and 64 showed Word stopping a relative climb, so `/../footnotes.xml` reads "
    "the note at `/footnotes.xml`; no session had shown Word such a target. One chunk: s74a names a footnotes part, which "
    "holds footnote 1 that the body references, by `/footnotes.xml`, `/../footnotes.xml`, `/../../footnotes.xml` and "
    "`/../word/footnotes.xml`, names it by `/../footnotes.xml` with the note only in `word/footnotes.xml`, names an "
    "endnotes part by `/../endnotes.xml`, and repeats session 64's relative `../../footnotes.xml`. It ran twice, as two "
    "separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session "
    "41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings "
    f"agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the "
    "first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator "
    f"revision in every row (`{rev}`), so the validator columns are a prediction this session tests.",
    "",
    "The driver opens files in name order, so the minimal controls were queued last and opened clean. Every clean notes "
    "row's PDF holds `Hello`, the note's mark (`1` for a footnote, `i` for an endnote) and `Note text`, so Word read the "
    "note from the part the climb stops at, and the controls hold `Hello` (`pdftotext`, both runs).",
    "",
    "- **A package-absolute climb stops at the root.** `/../footnotes.xml` and `/../../footnotes.xml` with the note in "
    "`/footnotes.xml`, `/../word/footnotes.xml` with it in `word/footnotes.xml`, and the endnotes twin `/../endnotes.xml` "
    "open clean and render the note, as `/footnotes.xml` and the relative `../../footnotes.xml` do.",
    "- **The climb names the root's part, not the source folder's.** `/../footnotes.xml` with the note only in "
    "`word/footnotes.xml` gets the recovery offer: the reference dangles, as session 64's relative climb did with the note "
    "in `word/`.",
    "",
    f"Word-valid at {at} accepts every clean row and rejects the refused one with `word-footnote-reference-missing`, "
    f"matching Word on {matches} of {len(rows)} rows. Strict reports `rels-broken` for each climb, as it did before #947.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 74</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 74 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s74builder.mts", ROOT / "s74builder.mts", "ts"), ("compare.py", ROOT / "s74/compare.py", "python"),
                         ("section.py", ROOT / "s74/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s74/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 75: 23:17Z–23:17Z on 2026-10-27, validator columns at a7249d62

Does Word stop an escaping target's climb at the package root for parts other than notes? Sessions 63, 64 and 74 showed it for footnotes and endnotes targets, which the note checks read since #830 and #947, while the file-reference walks still called such a target broken and the part it reaches unreferenced. One chunk: s75a stores session 71's caps styles part and its used header at the package root and names them by `../../<name>`, `/../<name>` and the in-package `../<name>`, beside each one's plain calibration and an escaping styles target whose part sits only in `word/`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 10 of 10 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`a7249d62a2f8a99508e26a8f717b982b476f8b78`).

The driver opens files in name order, so the minimal controls opened 4th and 5th, between the header rows and the styles rows. Every row opened clean, and its PDF shows what Word read (`pdftotext`, both runs):

- **Styles.** `HELLO` for the caps styles part at `/styles.xml` named by `../../styles.xml` and by `/../styles.xml`, as for the in-package `../styles.xml` and the plain calibration: Word applied the part the climb stops at.
- **Header.** `Head Hello` for the used header at `/header1.xml` named by `../../header1.xml`, as for its calibrations.
- **No fallback.** `Hello` for the caps styles part only in `word/styles.xml` named by `../../styles.xml`: the climb names the absent `/styles.xml`, and Word applied none of the source folder's part.

Word-valid at a7249d62 accepts every row, matching Word on 10 of 10, but strict reports `rels-broken`, `rels-unreferenced` and `rels-target-missing` for each escaping row, calling a part Word read broken and unreferenced ([#984](https://github.com/jandira-tech/docx-validate/issues/984)).

| Run    | Observed             | Specimen                                    | Shape                                                                                                                  | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at a7249d62 | strict at a7249d62                                                                           |
| ------ | -------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ---------------------- | -------------------------------------------------------------------------------------------- |
| `s75a` | 23:17:24Z, 23:17:35Z | `s75a-control-minimal`                      | control                                                                                                                | `ed0dc6b5b96ced7a` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |
| `s75a` | 23:17:24Z, 23:17:35Z | `styles-caps-calibration`                   | calibration: the caps styles part at word/styles.xml, named by styles.xml (Word applied it if the PDF reads HELLO)     | `383224d18ec2de6f` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |
| `s75a` | 23:17:24Z, 23:17:35Z | `styles-caps-at-root-one-level-calibration` | calibration: the caps styles part at /styles.xml, named by the in-package ../styles.xml                                | `81161b26965c6593` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |
| `s75a` | 23:17:24Z, 23:17:35Z | `styles-caps-at-root-escaping-two`          | the caps styles part at /styles.xml, named by ../../styles.xml (stopped at the root: /styles.xml)                      | `f1d9b812102abc82` | clean-open  | clean-open  | clean-open | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s75a` | 23:17:24Z, 23:17:35Z | `styles-caps-at-root-absolute-climb`        | the caps styles part at /styles.xml, named by /../styles.xml (stopped at the root: /styles.xml)                        | `08aec8d8ffac1886` | clean-open  | clean-open  | clean-open | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s75a` | 23:17:24Z, 23:17:35Z | `styles-caps-in-word-escaping-two`          | the caps styles part only at word/styles.xml, named by ../../styles.xml (stopped at the root: /styles.xml, not stored) | `238f50b373b12fa7` | clean-open  | clean-open  | clean-open | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s75a` | 23:17:24Z, 23:17:35Z | `header-calibration`                        | calibration: a used default header at word/header1.xml holding Head, named by header1.xml                              | `dd9219cb75fce501` | clean-open  | clean-open  | clean-open | valid                  | invalid: `paraid-missing-element`                                                            |
| `s75a` | 23:17:24Z, 23:17:35Z | `header-at-root-one-level-calibration`      | calibration: the used header at /header1.xml, named by the in-package ../header1.xml                                   | `94274161726be268` | clean-open  | clean-open  | clean-open | valid                  | invalid: `paraid-missing-element`                                                            |
| `s75a` | 23:17:24Z, 23:17:35Z | `header-at-root-escaping-two`               | the used header at /header1.xml, named by ../../header1.xml (stopped at the root: /header1.xml)                        | `e2c77b892c1a32cd` | clean-open  | clean-open  | clean-open | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s75a` | 23:17:24Z, 23:17:35Z | `s75a-control-minimal-end`                  | control                                                                                                                | `ed0dc6b5b96ced7a` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |

<details><summary>Raw records, session 75</summary>

```jsonl
{"run": "s75a", "pass": 1, "name": "s75a-control-minimal", "sha256": "ed0dc6b5b96ced7ac3627d2ecc5e0acfe3cec09bf1964541f698d331f9c8f8d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00004__wfv__s75a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s75a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "s75a-control-minimal", "sha256": "ed0dc6b5b96ced7ac3627d2ecc5e0acfe3cec09bf1964541f698d331f9c8f8d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00004__wfv__s75a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s75a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "styles-caps-calibration", "sha256": "383224d18ec2de6f176104cdb3227254acd0a877ca271cc6be48c43dbae2f2b2", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00008__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "styles-caps-calibration", "sha256": "383224d18ec2de6f176104cdb3227254acd0a877ca271cc6be48c43dbae2f2b2", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00008__wfv__styles-caps-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "styles-caps-at-root-one-level-calibration", "sha256": "81161b26965c6593af6430fd89b9ec26c194ae3106f3f585170623d3ace40598", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00007__wfv__styles-caps-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-one-level-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "styles-caps-at-root-one-level-calibration", "sha256": "81161b26965c6593af6430fd89b9ec26c194ae3106f3f585170623d3ace40598", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00007__wfv__styles-caps-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-one-level-calibration_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "styles-caps-at-root-escaping-two", "sha256": "f1d9b812102abc82184d107b519b23e9a953da6cd0e9dec87fbb6b23310299b2", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00006__wfv__styles-caps-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-escaping-two_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "styles-caps-at-root-escaping-two", "sha256": "f1d9b812102abc82184d107b519b23e9a953da6cd0e9dec87fbb6b23310299b2", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00006__wfv__styles-caps-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-escaping-two_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "styles-caps-at-root-absolute-climb", "sha256": "08aec8d8ffac1886a2139108e3fa165ffa424a9d9f87b39d16934680fb5277d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00005__wfv__styles-caps-at-root-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-absolute-climb_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "styles-caps-at-root-absolute-climb", "sha256": "08aec8d8ffac1886a2139108e3fa165ffa424a9d9f87b39d16934680fb5277d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00005__wfv__styles-caps-at-root-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-at-root-absolute-climb_byword.pdf (12657 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "styles-caps-in-word-escaping-two", "sha256": "238f50b373b12fa732ba7949bf96d81f6feacf79c8e8e905aee4154f0df8f16d", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00009__wfv__styles-caps-in-word-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-in-word-escaping-two_byword.pdf (8282 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "styles-caps-in-word-escaping-two", "sha256": "238f50b373b12fa732ba7949bf96d81f6feacf79c8e8e905aee4154f0df8f16d", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00009__wfv__styles-caps-in-word-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-caps-in-word-escaping-two_byword.pdf (8282 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "header-calibration", "sha256": "dd9219cb75fce501fd0cfb79d15c3bc27a8fe4879def2b0ff76f7f8f86874744", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00002__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "header-calibration", "sha256": "dd9219cb75fce501fd0cfb79d15c3bc27a8fe4879def2b0ff76f7f8f86874744", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00002__wfv__header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "header-at-root-one-level-calibration", "sha256": "94274161726be268a808a8dc30c400b04aa5d21d167a80ae9ccf893eaa7ee24e", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00001__wfv__header-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-at-root-one-level-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "header-at-root-one-level-calibration", "sha256": "94274161726be268a808a8dc30c400b04aa5d21d167a80ae9ccf893eaa7ee24e", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00001__wfv__header-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-at-root-one-level-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "header-at-root-escaping-two", "sha256": "e2c77b892c1a32cd1eab555dea601ef0a5b27182ddc08788b66b1111b7f023f9", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00000__wfv__header-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-at-root-escaping-two_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "header-at-root-escaping-two", "sha256": "e2c77b892c1a32cd1eab555dea601ef0a5b27182ddc08788b66b1111b7f023f9", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00000__wfv__header-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-at-root-escaping-two_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 1, "name": "s75a-control-minimal-end", "sha256": "ed0dc6b5b96ced7ac3627d2ecc5e0acfe3cec09bf1964541f698d331f9c8f8d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:24+00:00", "staged": "00003__wfv__s75a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s75a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s75a", "pass": 2, "name": "s75a-control-minimal-end", "sha256": "ed0dc6b5b96ced7ac3627d2ecc5e0acfe3cec09bf1964541f698d331f9c8f8d6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:17:35+00:00", "staged": "00003__wfv__s75a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s75a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 75 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s75builder.mts`:

```ts
// Session 75 (2026-10-27): does Word stop an escaping target's climb at the package root for parts other than notes?
// Sessions 63, 64 and 74 showed it for footnotes and endnotes targets (`../../footnotes.xml`, `/../footnotes.xml`),
// which the note checks read since #830 and #947. The file-reference walks (rels-broken, rels-target-missing,
// rels-unreferenced) still resolve a file-system path and drop an escaping target, so strict calls such a target broken
// and the part it reaches unreferenced, beside a note check that reads that part. s75a stores session 71's caps styles
// part and its used header at the package root and names them by `../../<name>`, `/../<name>` and the in-package
// `../<name>`, beside each one's plain calibration and an escaping styles target whose part sits only in word/.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's,
// the styles and header helpers s73builder.mts's, generalised to a stored location.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s75a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

const STYLES = `${WML}.styles+xml`;
const HEADER = `${WML}.header+xml`;
const CAPS_STYLES = replaceOnce(
    P["word/styles.xml"]!,
    "<w:rPrDefault><w:rPr/></w:rPrDefault>",
    "<w:rPrDefault><w:rPr><w:caps/></w:rPr></w:rPrDefault>",
);
/** The minimal parts with the caps styles part stored at `stored` (its Override moved there) and named by `target`. */
const capsStylesStoredAt = (stored: string, target: string): Record<string, string> => {
    const parts: Record<string, string> = { ...P, [SIDECAR]: replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`) };
    delete parts["word/styles.xml"];
    parts[stored] = CAPS_STYLES;
    parts[CT] = replaceOnce(
        P[CT]!,
        `<Override PartName="/word/styles.xml" ContentType="${STYLES}"/>`,
        `<Override PartName="/${stored}" ContentType="${STYLES}"/>`,
    );
    return parts;
};
/** The minimal parts with a default header holding "Head" stored at `stored`, referenced from the section and named by `target`. */
const headerStoredAt = (stored: string, target: string): Record<string, string> => ({
    ...P,
    [MAIN]: replaceOnce(
        replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`),
        "<w:sectPr>",
        '<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>',
    ),
    [stored]: `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Head</w:t></w:r></w:p></w:hdr>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", target)),
    [CT]: overrides(P[CT]!, [stored, HEADER]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s75a: withControls("s75a", [
        [
            "styles-caps-calibration",
            "calibration: the caps styles part at word/styles.xml, named by styles.xml (Word applied it if the PDF reads HELLO)",
            () => buildDocx(capsStylesStoredAt("word/styles.xml", "styles.xml")),
        ],
        [
            "styles-caps-at-root-one-level-calibration",
            "calibration: the caps styles part at /styles.xml, named by the in-package ../styles.xml",
            () => buildDocx(capsStylesStoredAt("styles.xml", "../styles.xml")),
        ],
        [
            "styles-caps-at-root-escaping-two",
            "the caps styles part at /styles.xml, named by ../../styles.xml (stopped at the root: /styles.xml)",
            () => buildDocx(capsStylesStoredAt("styles.xml", "../../styles.xml")),
        ],
        [
            "styles-caps-at-root-absolute-climb",
            "the caps styles part at /styles.xml, named by /../styles.xml (stopped at the root: /styles.xml)",
            () => buildDocx(capsStylesStoredAt("styles.xml", "/../styles.xml")),
        ],
        [
            "styles-caps-in-word-escaping-two",
            "the caps styles part only at word/styles.xml, named by ../../styles.xml (stopped at the root: /styles.xml, not stored)",
            () => buildDocx(capsStylesStoredAt("word/styles.xml", "../../styles.xml")),
        ],
        [
            "header-calibration",
            "calibration: a used default header at word/header1.xml holding Head, named by header1.xml",
            () => buildDocx(headerStoredAt("word/header1.xml", "header1.xml")),
        ],
        [
            "header-at-root-one-level-calibration",
            "calibration: the used header at /header1.xml, named by the in-package ../header1.xml",
            () => buildDocx(headerStoredAt("header1.xml", "../header1.xml")),
        ],
        [
            "header-at-root-escaping-two",
            "the used header at /header1.xml, named by ../../header1.xml (stopped at the root: /header1.xml)",
            () => buildDocx(headerStoredAt("header1.xml", "../../header1.xml")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-75 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s75a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s75/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-75 parts of docs/plans/evidence/word-probes-2026-10-24.md into s75/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s75a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s75/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED: set[str] = set()
# The narrative's claims about outcomes, checked against results.json: Word opened every row clean and word-valid, at
# the revision before #984, accepted each one.
for (label, file), r in results.items():
    assert r["outcome"] == "clean-open" and r["validatorMatchesWord"], (file, r)
assert agreed == len(rows) == 10, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the controls opened 4th and 5th, between the header rows and the styles rows.
ORDER = {
    "s75a": ["header-at-root-escaping-two.docx", "header-at-root-one-level-calibration.docx", "header-calibration.docx",
             "s75a-control-minimal-end.docx", "s75a-control-minimal.docx", "styles-caps-at-root-absolute-climb.docx",
             "styles-caps-at-root-escaping-two.docx", "styles-caps-at-root-one-level-calibration.docx",
             "styles-caps-calibration.docx", "styles-caps-in-word-escaping-two.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: `HELLO` when Word applied the caps styles part the target names,
# `Head Hello` when it rendered the header, and `Hello` for the controls and for the climb whose stopped part is absent.
EXPECTED = {
    "header-at-root-escaping-two.docx": "Head Hello", "header-at-root-one-level-calibration.docx": "Head Hello",
    "header-calibration.docx": "Head Hello", "styles-caps-at-root-absolute-climb.docx": "HELLO",
    "styles-caps-at-root-escaping-two.docx": "HELLO", "styles-caps-at-root-one-level-calibration.docx": "HELLO",
    "styles-caps-calibration.docx": "HELLO", "styles-caps-in-word-escaping-two.docx": "Hello",
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            text = rendered(run, file)
            assert text == EXPECTED.get(file, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 75: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Does Word stop an escaping target's climb at the package root for parts other than notes? Sessions 63, 64 and 74 "
    "showed it for footnotes and endnotes targets, which the note checks read since #830 and #947, while the "
    "file-reference walks still called such a target broken and the part it reaches unreferenced. One chunk: s75a "
    "stores session 71's caps styles part and its used header at the package root and names them by `../../<name>`, "
    "`/../<name>` and the in-package `../<name>`, beside each one's plain calibration and an escaping styles target "
    "whose part sits only in `word/`. It ran twice, as two separate driver runs of byte-identical copies, and each run's "
    "rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is "
    f"the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows "
    "agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of "
    f"the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, so the minimal controls opened 4th and 5th, between the header rows and the "
    "styles rows. Every row opened clean, and its PDF shows what Word read (`pdftotext`, both runs):",
    "",
    "- **Styles.** `HELLO` for the caps styles part at `/styles.xml` named by `../../styles.xml` and by "
    "`/../styles.xml`, as for the in-package `../styles.xml` and the plain calibration: Word applied the part the climb "
    "stops at.",
    "- **Header.** `Head Hello` for the used header at `/header1.xml` named by `../../header1.xml`, as for its "
    "calibrations.",
    "- **No fallback.** `Hello` for the caps styles part only in `word/styles.xml` named by `../../styles.xml`: the "
    "climb names the absent `/styles.xml`, and Word applied none of the source folder's part.",
    "",
    f"Word-valid at {at} accepts every row, matching Word on {matches} of {len(rows)}, but strict reports `rels-broken`, "
    "`rels-unreferenced` and `rels-target-missing` for each escaping row, calling a part Word read broken and "
    "unreferenced ([#984](https://github.com/jandira-tech/docx-validate/issues/984)).",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 75</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 75 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s75builder.mts", ROOT / "s75builder.mts", "ts"), ("compare.py", ROOT / "s75/compare.py", "python"),
                         ("section.py", ROOT / "s75/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s75/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 76: 23:19Z–23:19Z on 2026-10-27, validator columns at a7249d62

An existing package-root customXml part named by an escaping target. Session 54 refused an absent root `customXml/item1.xml` spelled `../../customXml/item1.xml`, and a broken customXml reference outside `word/` blocks word-valid (#734). `validateFileReferences` pushed every escaping target as broken, registered with the part the climb reaches, so word-valid also rejected a stored one. One chunk: s76a names a stored root customXml item, with its itemProps, from the main document's sidecar by the in-package `../customXml/item1.xml` and `/customXml/item1.xml` (calibrations) and by the escaping `../../customXml/item1.xml`, `../../../customXml/item1.xml` and `/../customXml/item1.xml`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 7 of 7 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`a7249d62a2f8a99508e26a8f717b982b476f8b78`).

The driver opens files in name order, so the minimal controls opened last. Every row opened clean, and every PDF holds `Hello` (`pdftotext`, both runs).

- **Escaping customXml targets open clean.** `../../customXml/item1.xml`, `../../../customXml/item1.xml` and `/../customXml/item1.xml` with the item stored at the root open as cleanly as the in-package calibrations: the climb stops at the root, where the part is stored.

Word-valid at a7249d62 rejects the three escaping rows with `rels-broken`, matching Word on only 4 of 7 rows: false rejections, fixed by [#984](https://github.com/jandira-tech/docx-validate/issues/984).

| Run    | Observed             | Specimen                          | Shape                                                                                      | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at a7249d62 | strict at a7249d62                                                 |
| ------ | -------------------- | --------------------------------- | ------------------------------------------------------------------------------------------ | ------------------ | ----------- | ----------- | ---------- | ---------------------- | ------------------------------------------------------------------ |
| `s76a` | 23:19:01Z, 23:19:12Z | `s76a-control-minimal`            | control                                                                                    | `eae12c7f631112a0` | clean-open  | clean-open  | clean-open | valid                  | valid                                                              |
| `s76a` | 23:19:01Z, 23:19:12Z | `customxml-one-level-calibration` | calibration: a stored root customXml/item1.xml named from word/ by ../customXml/item1.xml  | `9e27dae80ff68712` | clean-open  | clean-open  | clean-open | valid                  | valid                                                              |
| `s76a` | 23:19:01Z, 23:19:12Z | `customxml-absolute-calibration`  | calibration: the same, named by the package-absolute /customXml/item1.xml                  | `c795f83d1f15304b` | clean-open  | clean-open  | clean-open | valid                  | valid                                                              |
| `s76a` | 23:19:01Z, 23:19:12Z | `customxml-escaping-two`          | the same, named by ../../customXml/item1.xml (stopped at the root: customXml/item1.xml)    | `a2e59effb699b2c2` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing` |
| `s76a` | 23:19:01Z, 23:19:12Z | `customxml-escaping-three`        | the same, named by ../../../customXml/item1.xml (stopped at the root: customXml/item1.xml) | `5c97492727b67606` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing` |
| `s76a` | 23:19:01Z, 23:19:12Z | `customxml-absolute-climb`        | the same, named by /../customXml/item1.xml (stopped at the root: customXml/item1.xml)      | `a96a44ff64cd2e40` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing` |
| `s76a` | 23:19:01Z, 23:19:12Z | `s76a-control-minimal-end`        | control                                                                                    | `752d2bf1aa4cc858` | clean-open  | clean-open  | clean-open | valid                  | valid                                                              |

<details><summary>Raw records, session 76</summary>

```jsonl
{"run": "s76a", "pass": 1, "name": "s76a-control-minimal", "sha256": "eae12c7f631112a0a5be4b54e3be15e548e07f83e165092097c6fa6e75f41e20", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00006__wfv__s76a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s76a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "s76a-control-minimal", "sha256": "eae12c7f631112a0a5be4b54e3be15e548e07f83e165092097c6fa6e75f41e20", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00006__wfv__s76a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s76a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "customxml-one-level-calibration", "sha256": "9e27dae80ff68712b9a3f0fd83915773332709a0f4e83914b068e2c3b9e72ec6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00004__wfv__customxml-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-one-level-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "customxml-one-level-calibration", "sha256": "9e27dae80ff68712b9a3f0fd83915773332709a0f4e83914b068e2c3b9e72ec6", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00004__wfv__customxml-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-one-level-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "customxml-absolute-calibration", "sha256": "c795f83d1f15304b6716cad5b4d584e18b0ed3aeca640b76248f3087acd4bb0b", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00000__wfv__customxml-absolute-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-absolute-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "customxml-absolute-calibration", "sha256": "c795f83d1f15304b6716cad5b4d584e18b0ed3aeca640b76248f3087acd4bb0b", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00000__wfv__customxml-absolute-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-absolute-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "customxml-escaping-two", "sha256": "a2e59effb699b2c26a50da61ebed19f0c68ec1e0c45eaab5ca58e02fcb3f3a33", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00003__wfv__customxml-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-escaping-two_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "customxml-escaping-two", "sha256": "a2e59effb699b2c26a50da61ebed19f0c68ec1e0c45eaab5ca58e02fcb3f3a33", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00003__wfv__customxml-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-escaping-two_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "customxml-escaping-three", "sha256": "5c97492727b6760620bccf573bd91e43217fa399736f4c97c728869fa5a979ea", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00002__wfv__customxml-escaping-three.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-escaping-three_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "customxml-escaping-three", "sha256": "5c97492727b6760620bccf573bd91e43217fa399736f4c97c728869fa5a979ea", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00002__wfv__customxml-escaping-three.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-escaping-three_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "customxml-absolute-climb", "sha256": "a96a44ff64cd2e400ab2da4620c68f979ceb5df46cc2aa7895c0dd3cf0fb1352", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00001__wfv__customxml-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-absolute-climb_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "customxml-absolute-climb", "sha256": "a96a44ff64cd2e400ab2da4620c68f979ceb5df46cc2aa7895c0dd3cf0fb1352", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00001__wfv__customxml-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-absolute-climb_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 1, "name": "s76a-control-minimal-end", "sha256": "752d2bf1aa4cc8586c8ecc914155e50aad4bcf76b81686cba1b559bf74e37b1f", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:01+00:00", "staged": "00005__wfv__s76a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s76a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s76a", "pass": 2, "name": "s76a-control-minimal-end", "sha256": "752d2bf1aa4cc8586c8ecc914155e50aad4bcf76b81686cba1b559bf74e37b1f", "validatorRevision": "a7249d62a2f8a99508e26a8f717b982b476f8b78", "observedAt": "2026-10-27T23:19:12+00:00", "staged": "00005__wfv__s76a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s76a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 76 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s76builder.mts`:

```ts
// Session 76 (2026-10-27): an existing package-root customXml part named by an escaping target. Session 54 refused an
// absent root `customXml/item1.xml` spelled `../../customXml/item1.xml`, and sessions 63, 64, 74 and 75 showed Word
// stopping an escaping climb at the root for notes, styles and header targets. validateFileReferences pushes every
// escaping target as broken, registered with the part the climb reaches, so word-valid blocks an existing root
// customXml part named by `../../customXml/item1.xml` or `/../customXml/item1.xml` (a broken customXml reference outside
// word/ blocks, #734). s76a names a stored root customXml item (with its itemProps) from the main document's sidecar by
// the in-package `../customXml/item1.xml` and `/customXml/item1.xml` (calibrations) and the escaping
// `../../customXml/item1.xml`, `../../../customXml/item1.xml` and `/../customXml/item1.xml`.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s76a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

const ITEM = `${XML_DECL}<root xmlns="urn:example:data"><v>1</v></root>`;
const ITEM_PROPS = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<ds:datastoreItem ds:itemID="{11111111-2222-3333-4444-555555555555}" xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml"><ds:schemaRefs/></ds:datastoreItem>`;
/** The minimal parts with a stored customXml/item1.xml and its itemProps, named from the main document's sidecar by `target`. */
const customXmlAt = (target: string): Record<string, string> => ({
    ...P,
    "customXml/item1.xml": ITEM,
    "customXml/itemProps1.xml": ITEM_PROPS,
    "customXml/_rels/item1.xml.rels": `${XML_DECL}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationship("rId1", "customXmlProps", "itemProps1.xml")}</Relationships>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdX", "customXml", target)),
    [CT]: overrides(P[CT]!, ["customXml/itemProps1.xml", "application/vnd.openxmlformats-officedocument.customXmlProperties+xml"]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s76a: withControls("s76a", [
        [
            "customxml-one-level-calibration",
            "calibration: a stored root customXml/item1.xml named from word/ by ../customXml/item1.xml",
            () => buildDocx(customXmlAt("../customXml/item1.xml")),
        ],
        [
            "customxml-absolute-calibration",
            "calibration: the same, named by the package-absolute /customXml/item1.xml",
            () => buildDocx(customXmlAt("/customXml/item1.xml")),
        ],
        [
            "customxml-escaping-two",
            "the same, named by ../../customXml/item1.xml (stopped at the root: customXml/item1.xml)",
            () => buildDocx(customXmlAt("../../customXml/item1.xml")),
        ],
        [
            "customxml-escaping-three",
            "the same, named by ../../../customXml/item1.xml (stopped at the root: customXml/item1.xml)",
            () => buildDocx(customXmlAt("../../../customXml/item1.xml")),
        ],
        [
            "customxml-absolute-climb",
            "the same, named by /../customXml/item1.xml (stopped at the root: customXml/item1.xml)",
            () => buildDocx(customXmlAt("/../customXml/item1.xml")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-76 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s76a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s76/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-76 parts of docs/plans/evidence/word-probes-2026-10-24.md into s76/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s76a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s76/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED: set[str] = set()
ESCAPING = {"customxml-escaping-two.docx", "customxml-escaping-three.docx", "customxml-absolute-climb.docx"}
# The narrative's claims about outcomes, checked against results.json: Word opened every row clean; word-valid, at the
# revision before #984, rejected the three escaping rows and accepted the rest.
for (label, file), r in results.items():
    assert r["outcome"] == "clean-open", (file, r)
    assert r["wordValid"] is (file not in ESCAPING), (file, r)
assert agreed == len(rows) == 7, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the controls opened last.
ORDER = {
    "s76a": ["customxml-absolute-calibration.docx", "customxml-absolute-climb.docx", "customxml-escaping-three.docx",
             "customxml-escaping-two.docx", "customxml-one-level-calibration.docx", "s76a-control-minimal-end.docx",
             "s76a-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: the main document's "Hello" (a customXml item renders nothing).
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            text = rendered(run, file)
            assert text == "Hello", (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 76: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "An existing package-root customXml part named by an escaping target. Session 54 refused an absent root "
    "`customXml/item1.xml` spelled `../../customXml/item1.xml`, and a broken customXml reference outside `word/` blocks "
    "word-valid (#734). `validateFileReferences` pushed every escaping target as broken, registered with the part the "
    "climb reaches, so word-valid also rejected a stored one. One chunk: s76a names a stored root customXml item, with "
    "its itemProps, from the main document's sidecar by the in-package `../customXml/item1.xml` and "
    "`/customXml/item1.xml` (calibrations) and by the escaping `../../customXml/item1.xml`, "
    "`../../../customXml/item1.xml` and `/../customXml/item1.xml`. It ran twice, as two separate driver runs of "
    "byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and "
    "by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen. The builder recorded the validator revision in every row "
    f"(`{rev}`).",
    "",
    "The driver opens files in name order, so the minimal controls opened last. Every row opened clean, and every PDF "
    "holds `Hello` (`pdftotext`, both runs).",
    "",
    "- **Escaping customXml targets open clean.** `../../customXml/item1.xml`, `../../../customXml/item1.xml` and "
    "`/../customXml/item1.xml` with the item stored at the root open as cleanly as the in-package calibrations: the "
    "climb stops at the root, where the part is stored.",
    "",
    f"Word-valid at {at} rejects the three escaping rows with `rels-broken`, matching Word on only {matches} of "
    f"{len(rows)} rows: false rejections, fixed by [#984](https://github.com/jandira-tech/docx-validate/issues/984).",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 76</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 76 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s76builder.mts", ROOT / "s76builder.mts", "ts"), ("compare.py", ROOT / "s76/compare.py", "python"),
                         ("section.py", ROOT / "s76/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s76/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 77: 23:45Z–23:46Z on 2026-10-27, validator columns at 5c1e28f1

A comments part reached by an escaping target. Sessions 74 to 76 showed Word stopping an escaping climb at the package root for notes, styles, header and customXml targets, and #984 made the file-reference walks read it so. The read model still dropped an escaping target, so the comment checks read no comments part and word-valid blocked a body `w:commentReference` whose comment sits at `/comments.xml` (#896's rule: a comments part no relationship names defines nothing). One chunk: s77a stores comment 0, which the body marks and references, in `word/comments.xml` named by `comments.xml` and at `/comments.xml` named by the in-package `../comments.xml` (calibrations), at `/comments.xml` named by `../../comments.xml` and `/../comments.xml`, and only in `word/comments.xml` named by `../../comments.xml`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 7 of 7 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`5c1e28f15ed3e0738334576523bc3724ecc78a8d`).

The driver opens files in name order, so the minimal controls opened last. Every PDF Word printed holds `Hello`, and every comment row Word opened clean holds `Commented [1]: Note` too (`pdftotext`, both runs); the recovery row printed no PDF.

- **Escaping comments targets reach the root.** `../../comments.xml` and `/../comments.xml` with the comment at `/comments.xml` open clean and render the comment, as the in-package `../comments.xml` calibration does: the climb stops at the root, where the part is stored.
- **The climb does not fall back to the source folder.** `../../comments.xml` with the comment only in `word/comments.xml` gets the recovery offer: the climb names the absent `/comments.xml`, as the session 75 styles climb named the absent `/styles.xml`.

Word-valid at 5c1e28f1 rejects the two escaping rows Word opened clean with `comment-marker-missing`, matching Word on 5 of 7 rows: false rejections, fixed by [#986](https://github.com/jandira-tech/docx-validate/issues/986). Its rejection of the recovery row matches Word.

| Run    | Observed             | Specimen                                 | Shape                                                                                                             | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 5c1e28f1            | strict at 5c1e28f1                                                                                                     |
| ------ | -------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `s77a` | 23:45:42Z, 23:46:09Z | `s77a-control-minimal`                   | control                                                                                                           | `05d7374f73657813` | clean-open     | clean-open     | clean-open                 | valid                             | valid                                                                                                                  |
| `s77a` | 23:45:42Z, 23:46:09Z | `comments-calibration`                   | calibration: comment 0 in word/comments.xml, named by comments.xml; the body references it                        | `b0c8f0a5b8ee76f7` | clean-open     | clean-open     | clean-open                 | valid                             | invalid: `paraid-missing-element`                                                                                      |
| `s77a` | 23:45:42Z, 23:46:09Z | `comments-at-root-one-level-calibration` | calibration: comment 0 in /comments.xml, named by the in-package ../comments.xml                                  | `c15d9809223f7dc8` | clean-open     | clean-open     | clean-open                 | valid                             | invalid: `paraid-missing-element`                                                                                      |
| `s77a` | 23:45:42Z, 23:46:09Z | `comments-at-root-escaping-two`          | comment 0 in /comments.xml, named by ../../comments.xml (stopped at the root: /comments.xml)                      | `ad51bc3431092129` | clean-open     | clean-open     | clean-open                 | invalid: `comment-marker-missing` | invalid: `comment-marker-missing`, `paraid-missing-element`                                                            |
| `s77a` | 23:45:42Z, 23:46:09Z | `comments-at-root-absolute-climb`        | comment 0 in /comments.xml, named by /../comments.xml (stopped at the root: /comments.xml)                        | `d91a07414fec40c4` | clean-open     | clean-open     | clean-open                 | invalid: `comment-marker-missing` | invalid: `comment-marker-missing`, `paraid-missing-element`                                                            |
| `s77a` | 23:45:42Z, 23:46:09Z | `comments-in-word-escaping-two`          | comment 0 only in word/comments.xml, named by ../../comments.xml (stopped at the root: /comments.xml, not stored) | `ca012678aee444b8` | repair-warning | repair-warning | unreadable-content-warning | invalid: `comment-marker-missing` | invalid: `rels-broken`, `rels-unreferenced`, `comment-marker-missing`, `paraid-missing-element`, `rels-target-missing` |
| `s77a` | 23:45:42Z, 23:46:09Z | `s77a-control-minimal-end`               | control                                                                                                           | `85edb34e2b25a7f5` | clean-open     | clean-open     | clean-open                 | valid                             | valid                                                                                                                  |

<details><summary>Raw records, session 77</summary>

```jsonl
{"run": "s77a", "pass": 1, "name": "s77a-control-minimal", "sha256": "05d7374f736578130839dfaaa195560f9b471ea8828e1cfb79b7c1308682c067", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00006__wfv__s77a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s77a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "s77a-control-minimal", "sha256": "05d7374f736578130839dfaaa195560f9b471ea8828e1cfb79b7c1308682c067", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00006__wfv__s77a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s77a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 1, "name": "comments-calibration", "sha256": "b0c8f0a5b8ee76f7f288679d7b4b8c46225f194d949c3c100eff0030144bdac4", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00003__wfv__comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-calibration_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "comments-calibration", "sha256": "b0c8f0a5b8ee76f7f288679d7b4b8c46225f194d949c3c100eff0030144bdac4", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00003__wfv__comments-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-calibration_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 1, "name": "comments-at-root-one-level-calibration", "sha256": "c15d9809223f7dc85bf4fae57689e9e93a744c53caeeccbd1ed353588f14b18b", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00002__wfv__comments-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-one-level-calibration_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "comments-at-root-one-level-calibration", "sha256": "c15d9809223f7dc85bf4fae57689e9e93a744c53caeeccbd1ed353588f14b18b", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00002__wfv__comments-at-root-one-level-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-one-level-calibration_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 1, "name": "comments-at-root-escaping-two", "sha256": "ad51bc3431092129d67abe512f0fe3a0e23f63dbf11434236477bcea9685f341", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00001__wfv__comments-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-escaping-two_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "comments-at-root-escaping-two", "sha256": "ad51bc3431092129d67abe512f0fe3a0e23f63dbf11434236477bcea9685f341", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00001__wfv__comments-at-root-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-escaping-two_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 1, "name": "comments-at-root-absolute-climb", "sha256": "d91a07414fec40c46f21948ddb29ff71ab5d5019dba35d5909ae4df97ac8f346", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00000__wfv__comments-at-root-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-absolute-climb_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "comments-at-root-absolute-climb", "sha256": "d91a07414fec40c46f21948ddb29ff71ab5d5019dba35d5909ae4df97ac8f346", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00000__wfv__comments-at-root-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-at-root-absolute-climb_byword.pdf (34302 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 1, "name": "comments-in-word-escaping-two", "sha256": "ca012678aee444b8b4924a4f244e51b90aaacd2c77d2bd68d7486cdd14bda539", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00004__wfv__comments-in-word-escaping-two.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 19:45:41.210 \"Word found unreadable content in 00004__wfv__comments-in-word-escaping-two.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s77a", "pass": 2, "name": "comments-in-word-escaping-two", "sha256": "ca012678aee444b8b4924a4f244e51b90aaacd2c77d2bd68d7486cdd14bda539", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00004__wfv__comments-in-word-escaping-two.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 19:46:08.331 \"Word found unreadable content in 00004__wfv__comments-in-word-escaping-two.docx. Do you want to rec … ? If you trust the source of this document, click Yes.\""]}
{"run": "s77a", "pass": 1, "name": "s77a-control-minimal-end", "sha256": "85edb34e2b25a7f52d316bcc2c1c4bf5af6f992982d8ff27aa3353801965014f", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:45:42+00:00", "staged": "00005__wfv__s77a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s77a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s77a", "pass": 2, "name": "s77a-control-minimal-end", "sha256": "85edb34e2b25a7f52d316bcc2c1c4bf5af6f992982d8ff27aa3353801965014f", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:46:09+00:00", "staged": "00005__wfv__s77a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s77a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 77 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s77builder.mts`:

```ts
// Session 77 (2026-10-27): a comments part reached by an escaping target. Sessions 74 to 76 showed Word stopping an
// escaping climb at the package root for notes, styles, header and customXml targets, and #984 made the file-reference
// walks read it so. The read model (`wordReadTypedTargets`) still drops an escaping target, so the comment checks read
// no comments part and word-valid blocks a body `w:commentReference` whose comment sits at `/comments.xml`, named by
// `../../comments.xml` or `/../comments.xml` (#896's rule: a related comments part none is stored for defines nothing).
// s77a: the comment in word/comments.xml named by comments.xml and at /comments.xml named by the in-package
// ../comments.xml (calibrations), at /comments.xml named by ../../comments.xml and /../comments.xml, and only in
// word/comments.xml named by ../../comments.xml (the climb names the absent /comments.xml).
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s77a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The minimal parts with a body comment 0 (range and reference) whose comment sits at `stored`, named by `target`. */
const commentsAt = (stored: string, target: string): Record<string, string> => ({
    ...P,
    [MAIN]: replaceOnce(
        P[MAIN]!,
        "<w:r><w:t>Hello</w:t></w:r>",
        '<w:commentRangeStart w:id="0"/><w:r><w:t>Hello</w:t></w:r><w:commentRangeEnd w:id="0"/><w:r><w:commentReference w:id="0"/></w:r>',
    ),
    [stored]: `${XML_DECL}<w:comments xmlns:w="${W}"><w:comment w:id="0" w:author="a"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:comment></w:comments>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "comments", target)),
    [CT]: overrides(P[CT]!, [stored, `${WML}.comments+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s77a: withControls("s77a", [
        [
            "comments-calibration",
            "calibration: comment 0 in word/comments.xml, named by comments.xml; the body references it",
            () => buildDocx(commentsAt("word/comments.xml", "comments.xml")),
        ],
        [
            "comments-at-root-one-level-calibration",
            "calibration: comment 0 in /comments.xml, named by the in-package ../comments.xml",
            () => buildDocx(commentsAt("comments.xml", "../comments.xml")),
        ],
        [
            "comments-at-root-escaping-two",
            "comment 0 in /comments.xml, named by ../../comments.xml (stopped at the root: /comments.xml)",
            () => buildDocx(commentsAt("comments.xml", "../../comments.xml")),
        ],
        [
            "comments-at-root-absolute-climb",
            "comment 0 in /comments.xml, named by /../comments.xml (stopped at the root: /comments.xml)",
            () => buildDocx(commentsAt("comments.xml", "/../comments.xml")),
        ],
        [
            "comments-in-word-escaping-two",
            "comment 0 only in word/comments.xml, named by ../../comments.xml (stopped at the root: /comments.xml, not stored)",
            () => buildDocx(commentsAt("word/comments.xml", "../../comments.xml")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-77 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s77a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s77/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-77 parts of docs/plans/evidence/word-probes-2026-10-24.md into s77/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s77a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s77/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"comments-in-word-escaping-two.docx"}
ESCAPING = {"comments-at-root-escaping-two.docx", "comments-at-root-absolute-climb.docx"}
# The narrative's claims about outcomes, checked against results.json: Word opened every row clean but the comment held
# only in word/comments.xml behind ../../comments.xml, which got the recovery offer; word-valid, at the revision before
# #986, rejected that row and the two escaping rows Word opened clean, and accepted the rest.
for (label, file), r in results.items():
    assert r["outcome"] == ("unreadable-content-warning" if file in REFUSED else "clean-open"), (file, r)
    assert r["wordValid"] is (file not in ESCAPING | REFUSED), (file, r)
assert agreed == len(rows) == 7, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the controls opened last.
ORDER = {
    "s77a": ["comments-at-root-absolute-climb.docx", "comments-at-root-escaping-two.docx", "comments-at-root-one-level-calibration.docx",
             "comments-calibration.docx", "comments-in-word-escaping-two.docx", "s77a-control-minimal-end.docx",
             "s77a-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: the main document's "Hello", with the comment's margin balloon in every
# comment row Word opened clean; the recovery row printed no PDF.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                assert not (run / "pdf" / (Path(file).stem + "_byword.pdf")).exists(), (run, file)
                continue
            text = rendered(run, file)
            assert text == ("Hello" if "control" in file else "Hello Commented [1]: Note"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 77: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "A comments part reached by an escaping target. Sessions 74 to 76 showed Word stopping an escaping climb at the "
    "package root for notes, styles, header and customXml targets, and #984 made the file-reference walks read it so. "
    "The read model still dropped an escaping target, so the comment checks read no comments part and word-valid "
    "blocked a body `w:commentReference` whose comment sits at `/comments.xml` (#896's rule: a comments part no "
    "relationship names defines nothing). One chunk: s77a stores comment 0, which the body marks and references, in "
    "`word/comments.xml` named by `comments.xml` and at `/comments.xml` named by the in-package `../comments.xml` "
    "(calibrations), at `/comments.xml` named by `../../comments.xml` and `/../comments.xml`, and only in "
    "`word/comments.xml` named by `../../comments.xml`. It ran twice, as two separate driver runs of byte-identical "
    "copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    "Shape is the builder's description of the specimen. The builder recorded the validator revision in every row "
    f"(`{rev}`).",
    "",
    "The driver opens files in name order, so the minimal controls opened last. Every PDF Word printed holds `Hello`, and "
    "every comment row Word opened clean holds `Commented [1]: Note` too (`pdftotext`, both runs); the recovery row "
    "printed no PDF.",
    "",
    "- **Escaping comments targets reach the root.** `../../comments.xml` and `/../comments.xml` with the comment at "
    "`/comments.xml` open clean and render the comment, as the in-package `../comments.xml` calibration does: the climb "
    "stops at the root, where the part is stored.",
    "- **The climb does not fall back to the source folder.** `../../comments.xml` with the comment only in "
    "`word/comments.xml` gets the recovery offer: the climb names the absent `/comments.xml`, as the session 75 styles "
    "climb named the absent `/styles.xml`.",
    "",
    f"Word-valid at {at} rejects the two escaping rows Word opened clean with `comment-marker-missing`, matching Word on "
    f"{matches} of {len(rows)} rows: false rejections, fixed by "
    "[#986](https://github.com/jandira-tech/docx-validate/issues/986). Its rejection of the recovery row matches Word.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 77</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 77 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s77builder.mts", ROOT / "s77builder.mts", "ts"), ("compare.py", ROOT / "s77/compare.py", "python"),
                         ("section.py", ROOT / "s77/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s77/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 78: 23:47Z–23:47Z on 2026-10-27, validator columns at 5c1e28f1

A main document named by an escaping `officeDocument` target. Sessions 74 to 77 showed Word stopping an escaping climb at the package root for notes, styles, header, customXml and comments targets; session 70 read package-absolute `officeDocument` targets, but none that climbs. The read model and the main-document checks dropped such a target, and `addComment` refused it as "outside the package". One chunk: s78a names `word/document.xml` from `_rels/.rels` by the plain `word/document.xml` (calibration, byte-identical to the controls), by `../word/document.xml`, `../../word/document.xml` and `/../word/document.xml`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 6 of 6 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`5c1e28f15ed3e0738334576523bc3724ecc78a8d`).

The driver opens files in name order, so the minimal controls opened last. Every row opened clean, and every PDF holds `Hello` (`pdftotext`, both runs).

- **Escaping officeDocument targets name the main document.** `../word/document.xml`, `../../word/document.xml` and `/../word/document.xml` open as cleanly as the plain target and render the main document: from the package root, the climb stops at once, so each names `word/document.xml`.

Word-valid at 5c1e28f1 rejects the three escaping rows with `word-main-document-part`, matching Word on only 3 of 6 rows: false rejections, fixed by [#986](https://github.com/jandira-tech/docx-validate/issues/986).

| Run    | Observed             | Specimen                   | Shape                                                                                         | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at 5c1e28f1             | strict at 5c1e28f1                 |
| ------ | -------------------- | -------------------------- | --------------------------------------------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ---------------------------------- | ---------------------------------- |
| `s78a` | 23:47:31Z, 23:47:46Z | `s78a-control-minimal`     | control                                                                                       | `610275769710e541` | clean-open  | clean-open  | clean-open | valid                              | valid                              |
| `s78a` | 23:47:31Z, 23:47:46Z | `main-calibration`         | calibration: the officeDocument target is word/document.xml                                   | `610275769710e541` | clean-open  | clean-open  | clean-open | valid                              | valid                              |
| `s78a` | 23:47:31Z, 23:47:46Z | `main-escaping-one`        | the officeDocument target is ../word/document.xml (stopped at the root: word/document.xml)    | `db5b14f40008ec9f` | clean-open  | clean-open  | clean-open | invalid: `word-main-document-part` | invalid: `word-main-document-part` |
| `s78a` | 23:47:31Z, 23:47:46Z | `main-escaping-two`        | the officeDocument target is ../../word/document.xml (stopped at the root: word/document.xml) | `7a3a34fa1e29be98` | clean-open  | clean-open  | clean-open | invalid: `word-main-document-part` | invalid: `word-main-document-part` |
| `s78a` | 23:47:31Z, 23:47:46Z | `main-absolute-climb`      | the officeDocument target is /../word/document.xml (stopped at the root: word/document.xml)   | `2f133f9291938ed3` | clean-open  | clean-open  | clean-open | invalid: `word-main-document-part` | invalid: `word-main-document-part` |
| `s78a` | 23:47:31Z, 23:47:46Z | `s78a-control-minimal-end` | control                                                                                       | `610275769710e541` | clean-open  | clean-open  | clean-open | valid                              | valid                              |

<details><summary>Raw records, session 78</summary>

```jsonl
{"run": "s78a", "pass": 1, "name": "s78a-control-minimal", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00005__wfv__s78a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s78a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "s78a-control-minimal", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00005__wfv__s78a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s78a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 1, "name": "main-calibration", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00001__wfv__main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "main-calibration", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00001__wfv__main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 1, "name": "main-escaping-one", "sha256": "db5b14f40008ec9f278a0b1ced8f81802461f20c3c70be22933e804d9d7163bf", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00002__wfv__main-escaping-one.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-escaping-one_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "main-escaping-one", "sha256": "db5b14f40008ec9f278a0b1ced8f81802461f20c3c70be22933e804d9d7163bf", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00002__wfv__main-escaping-one.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-escaping-one_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 1, "name": "main-escaping-two", "sha256": "7a3a34fa1e29be981aa5607dc6c1f92f5b20f61878c42e2d4bf9ee541a63c9c5", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00003__wfv__main-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-escaping-two_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "main-escaping-two", "sha256": "7a3a34fa1e29be981aa5607dc6c1f92f5b20f61878c42e2d4bf9ee541a63c9c5", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00003__wfv__main-escaping-two.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-escaping-two_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 1, "name": "main-absolute-climb", "sha256": "2f133f9291938ed3e1e8ef12284691c6622004ab2fd04574d689bac104fe8f85", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00000__wfv__main-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-absolute-climb_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "main-absolute-climb", "sha256": "2f133f9291938ed3e1e8ef12284691c6622004ab2fd04574d689bac104fe8f85", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00000__wfv__main-absolute-climb.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-absolute-climb_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 1, "name": "s78a-control-minimal-end", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:31+00:00", "staged": "00004__wfv__s78a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s78a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s78a", "pass": 2, "name": "s78a-control-minimal-end", "sha256": "610275769710e541d60ded5181b550c813005dbaa98801c5064c768021c4e000", "validatorRevision": "5c1e28f15ed3e0738334576523bc3724ecc78a8d", "observedAt": "2026-10-27T23:47:46+00:00", "staged": "00004__wfv__s78a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s78a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 78 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s78builder.mts`:

```ts
// Session 78 (2026-10-27): a main document named by an escaping officeDocument target. Sessions 74 to 77 showed Word
// stopping an escaping climb at the package root for notes, styles, header, customXml and comments targets; session 70
// read package-absolute officeDocument targets, but none that climbs. The read model drops an escaping target and
// addComment refuses one as "outside the package". s78a names word/document.xml from _rels/.rels by the plain
// `word/document.xml` (calibration), by `../word/document.xml`, `../../word/document.xml` and `/../word/document.xml`.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825).
// Run from a worktree root: CHUNK=s78a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );

/** The minimal parts with the main document named from _rels/.rels by `target`. */
const mainAt = (target: string): Record<string, string> => ({
    ...P,
    "_rels/.rels": replaceOnce(P["_rels/.rels"]!, 'Target="word/document.xml"', `Target="${target}"`),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s78a: withControls("s78a", [
        ["main-calibration", "calibration: the officeDocument target is word/document.xml", () => buildDocx(mainAt("word/document.xml"))],
        [
            "main-escaping-one",
            "the officeDocument target is ../word/document.xml (stopped at the root: word/document.xml)",
            () => buildDocx(mainAt("../word/document.xml")),
        ],
        [
            "main-escaping-two",
            "the officeDocument target is ../../word/document.xml (stopped at the root: word/document.xml)",
            () => buildDocx(mainAt("../../word/document.xml")),
        ],
        [
            "main-absolute-climb",
            "the officeDocument target is /../word/document.xml (stopped at the root: word/document.xml)",
            () => buildDocx(mainAt("/../word/document.xml")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-78 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s78a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s78/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-78 parts of docs/plans/evidence/word-probes-2026-10-24.md into s78/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s78a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s78/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED: set[str] = set()
ESCAPING = {"main-escaping-one.docx", "main-escaping-two.docx", "main-absolute-climb.docx"}
# The narrative's claims about outcomes, checked against results.json: Word opened every row clean; word-valid, at the
# revision before #986, rejected the three escaping rows and accepted the rest.
for (label, file), r in results.items():
    assert r["outcome"] == "clean-open", (file, r)
    assert r["wordValid"] is (file not in ESCAPING), (file, r)
assert agreed == len(rows) == 6, (agreed, len(rows))
# The calibration names its main document as the minimal package does, so it is byte-identical to the controls.
specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / "s78a/specimens.jsonl").read_text().splitlines()}
assert specs["main-calibration.docx"]["sha256"] == specs["s78a-control-minimal.docx"]["sha256"]
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the controls opened last.
ORDER = {
    "s78a": ["main-absolute-climb.docx", "main-calibration.docx", "main-escaping-one.docx", "main-escaping-two.docx",
             "s78a-control-minimal-end.docx", "s78a-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: the main document's "Hello".
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            text = rendered(run, file)
            assert text == "Hello", (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 78: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "A main document named by an escaping `officeDocument` target. Sessions 74 to 77 showed Word stopping an escaping "
    "climb at the package root for notes, styles, header, customXml and comments targets; session 70 read "
    "package-absolute `officeDocument` targets, but none that climbs. The read model and the main-document checks "
    "dropped such a target, and `addComment` refused it as \"outside the package\". One chunk: s78a names "
    "`word/document.xml` from `_rels/.rels` by the plain `word/document.xml` (calibration, byte-identical to the "
    "controls), by `../word/document.xml`, `../../word/document.xml` and `/../word/document.xml`. It ran twice, as two "
    "separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session "
    "41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings "
    f"agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the "
    "first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator "
    f"revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, so the minimal controls opened last. Every row opened clean, and every PDF "
    "holds `Hello` (`pdftotext`, both runs).",
    "",
    "- **Escaping officeDocument targets name the main document.** `../word/document.xml`, `../../word/document.xml` and "
    "`/../word/document.xml` open as cleanly as the plain target and render the main document: from the package root, "
    "the climb stops at once, so each names `word/document.xml`.",
    "",
    f"Word-valid at {at} rejects the three escaping rows with `word-main-document-part`, matching Word on only {matches} "
    f"of {len(rows)} rows: false rejections, fixed by [#986](https://github.com/jandira-tech/docx-validate/issues/986).",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 78</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 78 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s78builder.mts", ROOT / "s78builder.mts", "ts"), ("compare.py", ROOT / "s78/compare.py", "python"),
                         ("section.py", ROOT / "s78/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s78/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 79: 00:19Z–00:20Z on 2026-10-28, validator columns at 57df0b9a

Two questions sessions 70 to 73 left open. Every folder target Word refused there sat in a relationships part Word reads: `_rels/.rels` or the main document's. Since [#975](https://github.com/jandira-tech/docx-validate/issues/975), word-valid blocks a folder target in any relationships part, and since session 54 it blocks an absent escaping `customXml` target ([#734](https://github.com/jandira-tech/docx-validate/issues/734)), wherever the relationships part sits ([#987](https://github.com/jandira-tech/docx-validate/issues/987)). And the file-reference walk skipped every target starting with `http`, so a relative folder target spelled with that prefix drew nothing ([#988](https://github.com/jandira-tech/docx-validate/issues/988)). One chunk: s79a stores an unreferenced `word/stray.xml` whose sidecar `word/_rels/stray.xml.rels` relates the stored, unused `word/media/image1.png` by `media/image1.png` (calibration), by `media/image1.png/.` and by `.`, an absent `media/missing.png` (calibration), and an absent `../customXml/item1.xml`; it repeats s72a's `media/image1.png/.` from the main document's sidecar; and it relates an unused image stored as `word/httpimage1.png` from the main document's sidecar by `httpimage1.png` (calibration) and by `httpimage1.png/.`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 10 of 10 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6`).

The driver opens files in name order, so the two refused rows opened 2nd and 3rd, and both minimal controls opened right after them, clean. Every clean row's PDF holds `Hello` (`pdftotext`, both runs); the stray part and the unused images render nothing, as nothing references them.

- **A relationships part Word does not read.** In the stray part's sidecar, `media/image1.png/.`, `.` and the absent `../customXml/item1.xml` open as cleanly as its calibrations: no relationship names `word/stray.xml`, so Word never reads its relationships part. The same `media/image1.png/.` in the main document's sidecar gets the recovery offer again, as in session 72.
- **A relative target that starts with `http`.** `httpimage1.png/.` gets the recovery offer, while `httpimage1.png` opens clean: the prefix starts no URI scheme, so the target names a folder like any other.

Word-valid at 57df0b9a rejects the three stray-sidecar rows, three false rejections tracked by [#987](https://github.com/jandira-tech/docx-validate/issues/987), and accepts `httpimage1.png/.`, a false acceptance fixed by [#988](https://github.com/jandira-tech/docx-validate/issues/988). It matches Word on 6 of 10 rows.

| Run    | Observed             | Specimen                          | Shape                                                                                                                         | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 57df0b9a | strict at 57df0b9a                                                                                            |
| ------ | -------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| `s79a` | 00:19:31Z, 00:20:13Z | `s79a-control-minimal`            | control                                                                                                                       | `d4606453167424cc` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                         |
| `s79a` | 00:19:31Z, 00:20:13Z | `stray-image-calibration`         | calibration: an unreferenced word/stray.xml whose sidecar relates the stored unused word/media/image1.png by media/image1.png | `8dec59502aa23143` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-unreferenced`, `ct-undeclared-part`                                                            |
| `s79a` | 00:19:31Z, 00:20:13Z | `stray-image-final-dot`           | #987: the same stray sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)                              | `d92b1f8921560fdd` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-unreferenced`, `ct-undeclared-part`, `rels-target-missing` |
| `s79a` | 00:19:31Z, 00:20:13Z | `stray-image-dot`                 | #987: the same stray sidecar relates an image by . (a folder: word/)                                                          | `07d392661fb40e3b` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-unreferenced`, `ct-undeclared-part`, `rels-target-missing` |
| `s79a` | 00:19:31Z, 00:20:13Z | `stray-image-missing-calibration` | calibration: the same stray sidecar relates an absent media/missing.png                                                       | `b7cf758673c270f4` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `rels-unreferenced`, `ct-undeclared-part`, `rels-target-missing` |
| `s79a` | 00:19:31Z, 00:20:13Z | `stray-customxml-escaping-absent` | #987: the same stray sidecar relates an absent ../customXml/item1.xml (#734's blocking shape, session 54)                     | `dcdc4d0eb7a4a65d` | clean-open     | clean-open     | clean-open                 | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-unreferenced`, `ct-undeclared-part`, `rels-target-missing` |
| `s79a` | 00:19:31Z, 00:20:13Z | `main-image-final-dot`            | repeat of s72a: the main document's sidecar relates the stored unused word/media/image1.png by media/image1.png/.             | `c722e02a3a0e1914` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                                            |
| `s79a` | 00:19:31Z, 00:20:13Z | `http-image-calibration`          | calibration: an unused image stored as word/httpimage1.png, related from the main sidecar by httpimage1.png                   | `572b1dc0d9640617` | clean-open     | clean-open     | clean-open                 | valid                  | invalid: `rels-unreferenced`                                                                                  |
| `s79a` | 00:19:31Z, 00:20:13Z | `http-image-final-dot`            | #988: the same image related by httpimage1.png/. (a folder: word/httpimage1.png/)                                             | `97d84a62c5c23771` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-unreferenced`, `rels-target-missing`                                                           |
| `s79a` | 00:19:31Z, 00:20:13Z | `s79a-control-minimal-end`        | control                                                                                                                       | `1fe3a3d97b178eb6` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                                                                         |

<details><summary>Raw records, session 79</summary>

```jsonl
{"run": "s79a", "pass": 1, "name": "s79a-control-minimal", "sha256": "d4606453167424cc5c3ac8eae91c7f645a2d4c462d988d9fb987c6586402f7e9", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00004__wfv__s79a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s79a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "s79a-control-minimal", "sha256": "d4606453167424cc5c3ac8eae91c7f645a2d4c462d988d9fb987c6586402f7e9", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00004__wfv__s79a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s79a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "stray-image-calibration", "sha256": "8dec59502aa2314394f4c3e0f9f3073f4c2dc54f29b4ddeaade023fea56b403a", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00006__wfv__stray-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "stray-image-calibration", "sha256": "8dec59502aa2314394f4c3e0f9f3073f4c2dc54f29b4ddeaade023fea56b403a", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00006__wfv__stray-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "stray-image-final-dot", "sha256": "d92b1f8921560fdd09da5190c436283ea2d8c8a35de794e2ee1b64c0b8e09af8", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00008__wfv__stray-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "stray-image-final-dot", "sha256": "d92b1f8921560fdd09da5190c436283ea2d8c8a35de794e2ee1b64c0b8e09af8", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00008__wfv__stray-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "stray-image-dot", "sha256": "07d392661fb40e3b95f552a7aef569ceea2a3e72df8340d3858a83e571c13602", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00007__wfv__stray-image-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "stray-image-dot", "sha256": "07d392661fb40e3b95f552a7aef569ceea2a3e72df8340d3858a83e571c13602", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00007__wfv__stray-image-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "stray-image-missing-calibration", "sha256": "b7cf758673c270f472a11645cf75600e8d48eb7ae7f19eff9f24e1bdedd57987", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00009__wfv__stray-image-missing-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-missing-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "stray-image-missing-calibration", "sha256": "b7cf758673c270f472a11645cf75600e8d48eb7ae7f19eff9f24e1bdedd57987", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00009__wfv__stray-image-missing-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-image-missing-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "stray-customxml-escaping-absent", "sha256": "dcdc4d0eb7a4a65d3be8c766b985f9eb95c939619c270f5478fda51fe24d7715", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00005__wfv__stray-customxml-escaping-absent.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-customxml-escaping-absent_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "stray-customxml-escaping-absent", "sha256": "dcdc4d0eb7a4a65d3be8c766b985f9eb95c939619c270f5478fda51fe24d7715", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00005__wfv__stray-customxml-escaping-absent.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF stray-customxml-escaping-absent_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "main-image-final-dot", "sha256": "c722e02a3a0e19149987af7bd8b8fb131046ff232bb4948883701cf51396994f", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00002__wfv__main-image-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:19:25.712 'Word found unreadable content in 00002__wfv__main-image-final-dot.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s79a", "pass": 2, "name": "main-image-final-dot", "sha256": "c722e02a3a0e19149987af7bd8b8fb131046ff232bb4948883701cf51396994f", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00002__wfv__main-image-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:20:09.186 'Word found unreadable content in 00002__wfv__main-image-final-dot.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'", "2026-10-27 20:20:10.158 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ery converter. (00002__wfv__main-image-final-dot.docx)\""]}
{"run": "s79a", "pass": 1, "name": "http-image-calibration", "sha256": "572b1dc0d9640617e649ebabf2312e8ac9d138bfa02656b63a0534af51fcc2ce", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00000__wfv__http-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF http-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "http-image-calibration", "sha256": "572b1dc0d9640617e649ebabf2312e8ac9d138bfa02656b63a0534af51fcc2ce", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00000__wfv__http-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF http-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 1, "name": "http-image-final-dot", "sha256": "97d84a62c5c23771eefe0d99fde84465fdd3f867c8141e91c74c369fdb3513ee", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00001__wfv__http-image-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:18:47.342 'Word found unreadable content in 00001__wfv__http-image-final-dot.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'"]}
{"run": "s79a", "pass": 2, "name": "http-image-final-dot", "sha256": "97d84a62c5c23771eefe0d99fde84465fdd3f867c8141e91c74c369fdb3513ee", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00001__wfv__http-image-final-dot.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:20:04.504 'Word found unreadable content in 00001__wfv__http-image-final-dot.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'", "2026-10-27 20:20:05.542 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ery converter. (00001__wfv__http-image-final-dot.docx)\""]}
{"run": "s79a", "pass": 1, "name": "s79a-control-minimal-end", "sha256": "1fe3a3d97b178eb635a9e47bf497cffce5d593d652369a44169908cd1b435d53", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:19:31+00:00", "staged": "00003__wfv__s79a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s79a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s79a", "pass": 2, "name": "s79a-control-minimal-end", "sha256": "1fe3a3d97b178eb635a9e47bf497cffce5d593d652369a44169908cd1b435d53", "validatorRevision": "57df0b9a0ce7c9d40e2252fe50a5f93463bdf9b6", "observedAt": "2026-10-28T00:20:13+00:00", "staged": "00003__wfv__s79a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s79a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 79 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s79builder.mts`:

```ts
// Session 79 (2026-10-28): does Word refuse a folder target in a relationships part it never reads (#987), and a folder
// target spelled with an `http` prefix (#988)? Sessions 70 to 73 refused every folder target Word was shown, all in parts
// Word reads (`_rels/.rels` and the main document's sidecar), and #975 blocks word-valid on any folder target, in any
// relationships part. Sessions 36 and 37 showed Word ignoring malformed sidecars of parts it never loads.
// s79a: an unreferenced word/stray.xml whose sidecar word/_rels/stray.xml.rels relates the stored unused image by
// media/image1.png (calibration), media/image1.png/. and ., an absent media/missing.png (calibration), and an absent
// ../customXml/item1.xml (#734's blocking shape); session 72's main-sidecar media/image1.png/. row repeated; and an
// unused image stored as word/httpimage1.png related from the main sidecar by httpimage1.png (calibration) and
// httpimage1.png/. (#988).
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's,
// the image helper s72builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825), and its src (#985).
// Run from a worktree root: CHUNK=s79a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const STRAY = "word/stray.xml";
const STRAY_SIDECAR = "word/_rels/stray.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const withPng = (ct: string) => replaceOnce(ct, "</Types>", '<Default Extension="png" ContentType="image/png"/></Types>');

const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "base64"),
);
/** The minimal parts with word/media/image1.png stored, and an unreferenced word/stray.xml whose sidecar holds `rel`. */
const straySidecar = (rel: string): Record<string, string | Uint8Array> => ({
    ...P,
    "word/media/image1.png": PNG,
    [STRAY]: `${XML_DECL}<w:document xmlns:w="${W}"><w:body><w:p><w:r><w:t>Stray</w:t></w:r></w:p></w:body></w:document>`,
    [STRAY_SIDECAR]: `${XML_DECL}<Relationships xmlns="${PR}">${rel}</Relationships>`,
    [CT]: withPng(P[CT]!),
});
/** The minimal parts with an unused image stored at `stored`, related from the main document's sidecar by `target`. */
const unusedImageAt = (stored: string, target: string): Record<string, string | Uint8Array> => ({
    ...P,
    [stored]: PNG,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdI", "image", target)),
    [CT]: withPng(P[CT]!),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s79a: withControls("s79a", [
        [
            "stray-image-calibration",
            "calibration: an unreferenced word/stray.xml whose sidecar relates the stored unused word/media/image1.png by media/image1.png",
            () => buildDocx(straySidecar(relationship("rId1", "image", "media/image1.png"))),
        ],
        [
            "stray-image-final-dot",
            "#987: the same stray sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)",
            () => buildDocx(straySidecar(relationship("rId1", "image", "media/image1.png/."))),
        ],
        [
            "stray-image-dot",
            "#987: the same stray sidecar relates an image by . (a folder: word/)",
            () => buildDocx(straySidecar(relationship("rId1", "image", "."))),
        ],
        [
            "stray-image-missing-calibration",
            "calibration: the same stray sidecar relates an absent media/missing.png",
            () => buildDocx(straySidecar(relationship("rId1", "image", "media/missing.png"))),
        ],
        [
            "stray-customxml-escaping-absent",
            "#987: the same stray sidecar relates an absent ../customXml/item1.xml (#734's blocking shape, session 54)",
            () => buildDocx(straySidecar(relationship("rId1", "customXml", "../customXml/item1.xml"))),
        ],
        [
            "main-image-final-dot",
            "repeat of s72a: the main document's sidecar relates the stored unused word/media/image1.png by media/image1.png/.",
            () => buildDocx(unusedImageAt("word/media/image1.png", "media/image1.png/.")),
        ],
        [
            "http-image-calibration",
            "calibration: an unused image stored as word/httpimage1.png, related from the main sidecar by httpimage1.png",
            () => buildDocx(unusedImageAt("word/httpimage1.png", "httpimage1.png")),
        ],
        [
            "http-image-final-dot",
            "#988: the same image related by httpimage1.png/. (a folder: word/httpimage1.png/)",
            () => buildDocx(unusedImageAt("word/httpimage1.png", "httpimage1.png/.")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen for the staging and log-check
// scripts to pick up (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-79 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s79a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s79/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-79 parts of docs/plans/evidence/word-probes-2026-10-24.md into s79/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s79a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s79/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"main-image-final-dot.docx", "http-image-final-dot.docx"}
STRAY_FOLDERS = {"stray-image-final-dot.docx", "stray-image-dot.docx", "stray-customxml-escaping-absent.docx"}
# The narrative's claims about outcomes, checked against results.json: Word refused the main sidecar's folder target and
# the http-prefixed folder target, and opened every other row clean. Word-valid, at the revision before #987 and #988,
# rejected the three stray-sidecar rows and the main sidecar's folder target, and accepted the rest.
for (label, file), r in results.items():
    assert r["outcome"] == ("unreadable-content-warning" if file in REFUSED else "clean-open"), (file, r)
    assert r["wordValid"] is (file not in STRAY_FOLDERS | {"main-image-final-dot.docx"}), (file, r)
    assert r["validatorMatchesWord"] is (file not in STRAY_FOLDERS | {"http-image-final-dot.docx"}), (file, r)
assert agreed == len(rows) == 10, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the two refused rows opened 2nd and 3rd and the minimal controls right after them.
ORDER = {
    "s79a": ["http-image-calibration.docx", "http-image-final-dot.docx", "main-image-final-dot.docx",
             "s79a-control-minimal-end.docx", "s79a-control-minimal.docx", "stray-customxml-escaping-absent.docx",
             "stray-image-calibration.docx", "stray-image-dot.docx", "stray-image-final-dot.docx",
             "stray-image-missing-calibration.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each clean row, both runs: the main document's "Hello". The stray part and the unused images
# render nothing, as nothing references them.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            if file in REFUSED:
                continue
            text = rendered(run, file)
            assert text == "Hello", (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 79: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Two questions sessions 70 to 73 left open. Every folder target Word refused there sat in a relationships part Word "
    "reads: `_rels/.rels` or the main document's. Since [#975](https://github.com/jandira-tech/docx-validate/issues/975), "
    "word-valid blocks a folder target in any relationships part, and since session 54 it blocks an absent escaping "
    "`customXml` target ([#734](https://github.com/jandira-tech/docx-validate/issues/734)), wherever the relationships "
    "part sits ([#987](https://github.com/jandira-tech/docx-validate/issues/987)). And the file-reference walk skipped "
    "every target starting with `http`, so a relative folder target spelled with that prefix drew nothing "
    "([#988](https://github.com/jandira-tech/docx-validate/issues/988)). One chunk: s79a stores an unreferenced "
    "`word/stray.xml` whose sidecar `word/_rels/stray.xml.rels` relates the stored, unused `word/media/image1.png` by "
    "`media/image1.png` (calibration), by `media/image1.png/.` and by `.`, an absent `media/missing.png` (calibration), and "
    "an absent `../customXml/item1.xml`; it repeats s72a's `media/image1.png/.` from the main document's sidecar; and it "
    "relates an unused image stored as `word/httpimage1.png` from the main document's sidecar by `httpimage1.png` "
    "(calibration) and by `httpimage1.png/.`. It ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    f"is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} "
    "rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description "
    f"of the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, so the two refused rows opened 2nd and 3rd, and both minimal controls opened "
    "right after them, clean. Every clean row's PDF holds `Hello` (`pdftotext`, both runs); the stray part and the unused "
    "images render nothing, as nothing references them.",
    "",
    "- **A relationships part Word does not read.** In the stray part's sidecar, `media/image1.png/.`, `.` and the absent "
    "`../customXml/item1.xml` open as cleanly as its calibrations: no relationship names `word/stray.xml`, so Word never "
    "reads its relationships part. The same `media/image1.png/.` in the main document's sidecar gets the recovery offer "
    "again, as in session 72.",
    "- **A relative target that starts with `http`.** `httpimage1.png/.` gets the recovery offer, while `httpimage1.png` "
    "opens clean: the prefix starts no URI scheme, so the target names a folder like any other.",
    "",
    f"Word-valid at {at} rejects the three stray-sidecar rows, three false rejections tracked by "
    "[#987](https://github.com/jandira-tech/docx-validate/issues/987), and accepts `httpimage1.png/.`, a false acceptance "
    "fixed by [#988](https://github.com/jandira-tech/docx-validate/issues/988). It matches Word on "
    f"{matches} of {len(rows)} rows.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 79</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 79 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s79builder.mts", ROOT / "s79builder.mts", "ts"), ("compare.py", ROOT / "s79/compare.py", "python"),
                         ("section.py", ROOT / "s79/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s79/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 80: 00:30Z–00:30Z on 2026-10-28, validator columns at 2686b567

The scope of [#987](https://github.com/jandira-tech/docx-validate/issues/987). Session 79 opened clean a folder target and an absent escaping `customXml` target in the sidecar of a part nothing references, while the same folder target in the main document's sidecar got the recovery offer. Of the relationships parts, the read model lists only each story root's own sidecar, beside `_rels/.rels`; whether Word checks the targets in the sidecar of a part it does load was unprobed. One chunk: s80a stores the unused `word/media/image1.png` and a header `word/header1.xml` holding `Head`, related from the main document's sidecar and referenced by the section (used), whose sidecar `word/_rels/header1.xml.rels` relates the image by `media/image1.png` (calibration) and by `media/image1.png/.`, an absent `media/missing.png` (calibration) and an absent `../customXml/item1.xml`; the same header related but not referenced (unused) with `media/image1.png/.` in its sidecar; and the styles part's sidecar `word/_rels/styles.xml.rels` relating the image by `media/image1.png` (calibration) and by `media/image1.png/.`. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 9 of 9 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`2686b56714cb94a8c796fd0d033474e0f661a381`).

The driver opens files in name order, so the minimal controls opened 6th and 7th, between the header rows and the styles rows. Every row opened clean. Every used-header row's PDF holds `Head Hello`, so Word loaded the header, and every other row's holds `Hello` (`pdftotext`, both runs).

- **The sidecar of a part Word loads.** In the used header's sidecar, `media/image1.png/.` and the absent `../customXml/item1.xml` open as cleanly as the calibrations, and the header renders: Word loaded the header but did not check its relationships' targets. So do `media/image1.png/.` in the unused header's sidecar and in the styles part's.

With sessions 70 to 73 and 79, Word refused these targets only in `_rels/.rels` and in the main document's own relationships part. Word-valid at 2686b567 rejects the four rows with `rels-broken`, four false rejections, and matches Word on 5 of 9 rows; [#987](https://github.com/jandira-tech/docx-validate/issues/987) gates the block to the relationships parts the read model lists.

| Run    | Observed             | Specimen                                | Shape                                                                                                                  | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | word-valid at 2686b567 | strict at 2686b567                                                                           |
| ------ | -------------------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ---------------------- | -------------------------------------------------------------------------------------------- |
| `s80a` | 00:30:27Z, 00:30:38Z | `s80a-control-minimal`                  | control                                                                                                                | `03ca5c8ed7b05c19` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |
| `s80a` | 00:30:27Z, 00:30:38Z | `header-used-image-calibration`         | calibration: a used word/header1.xml whose sidecar relates the stored unused word/media/image1.png by media/image1.png | `4a16d5e1c3cfd768` | clean-open  | clean-open  | clean-open | valid                  | invalid: `paraid-missing-element`                                                            |
| `s80a` | 00:30:27Z, 00:30:38Z | `header-used-image-final-dot`           | #987: the used header's sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)                    | `5e099b8ba446feaf` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s80a` | 00:30:27Z, 00:30:38Z | `header-used-image-missing-calibration` | calibration: the used header's sidecar relates an absent media/missing.png                                             | `5cb59929f75cb1ae` | clean-open  | clean-open  | clean-open | valid                  | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s80a` | 00:30:27Z, 00:30:38Z | `header-used-customxml-escaping-absent` | #987: the used header's sidecar relates an absent ../customXml/item1.xml (#734's blocking shape, session 54)           | `b379ddde74a38969` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s80a` | 00:30:27Z, 00:30:38Z | `header-unused-image-final-dot`         | #987: the same header related but not referenced (unused); its sidecar relates the image by media/image1.png/.         | `9bb4950aa425bd42` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `paraid-missing-element`, `rels-target-missing` |
| `s80a` | 00:30:27Z, 00:30:38Z | `styles-image-calibration`              | calibration: the styles part's sidecar relates the stored unused word/media/image1.png by media/image1.png             | `a65f682e28a47196` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |
| `s80a` | 00:30:27Z, 00:30:38Z | `styles-image-final-dot`                | #987: the styles part's sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)                    | `5c3a4d3865ac989b` | clean-open  | clean-open  | clean-open | invalid: `rels-broken` | invalid: `rels-broken`, `rels-unreferenced`, `rels-target-missing`                           |
| `s80a` | 00:30:27Z, 00:30:38Z | `s80a-control-minimal-end`              | control                                                                                                                | `03ca5c8ed7b05c19` | clean-open  | clean-open  | clean-open | valid                  | valid                                                                                        |

<details><summary>Raw records, session 80</summary>

```jsonl
{"run": "s80a", "pass": 1, "name": "s80a-control-minimal", "sha256": "03ca5c8ed7b05c1932d5aa5a37dcdc71e5f9f7e410f4961bd8439b9e1647b194", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00006__wfv__s80a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s80a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "s80a-control-minimal", "sha256": "03ca5c8ed7b05c1932d5aa5a37dcdc71e5f9f7e410f4961bd8439b9e1647b194", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00006__wfv__s80a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s80a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "header-used-image-calibration", "sha256": "4a16d5e1c3cfd7684af80cd452cf510f0f444d1f29cd7c3e7f092465d62c13b6", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00002__wfv__header-used-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "header-used-image-calibration", "sha256": "4a16d5e1c3cfd7684af80cd452cf510f0f444d1f29cd7c3e7f092465d62c13b6", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00002__wfv__header-used-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "header-used-image-final-dot", "sha256": "5e099b8ba446feafebf65b35efd0319943534234227422ddcfc3ea27ead375c9", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00003__wfv__header-used-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-final-dot_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "header-used-image-final-dot", "sha256": "5e099b8ba446feafebf65b35efd0319943534234227422ddcfc3ea27ead375c9", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00003__wfv__header-used-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-final-dot_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "header-used-image-missing-calibration", "sha256": "5cb59929f75cb1aee966770538f1e5b6ca217bb527166f9da1e74e64660c9834", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00004__wfv__header-used-image-missing-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-missing-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "header-used-image-missing-calibration", "sha256": "5cb59929f75cb1aee966770538f1e5b6ca217bb527166f9da1e74e64660c9834", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00004__wfv__header-used-image-missing-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-image-missing-calibration_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "header-used-customxml-escaping-absent", "sha256": "b379ddde74a38969233494eaeccf389109e6a4c09d32bbb08735b7bb2dd4daaf", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00001__wfv__header-used-customxml-escaping-absent.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-customxml-escaping-absent_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "header-used-customxml-escaping-absent", "sha256": "b379ddde74a38969233494eaeccf389109e6a4c09d32bbb08735b7bb2dd4daaf", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00001__wfv__header-used-customxml-escaping-absent.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-used-customxml-escaping-absent_byword.pdf (14865 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "header-unused-image-final-dot", "sha256": "9bb4950aa425bd428a1328028e7df2b1a4ae013a6fc6d1cba54bd73725a29c5d", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00000__wfv__header-unused-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "header-unused-image-final-dot", "sha256": "9bb4950aa425bd428a1328028e7df2b1a4ae013a6fc6d1cba54bd73725a29c5d", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00000__wfv__header-unused-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "styles-image-calibration", "sha256": "a65f682e28a47196fffb5bfcc5040805c78d2ba1d75e7a693f6f9d9a47657581", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00007__wfv__styles-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "styles-image-calibration", "sha256": "a65f682e28a47196fffb5bfcc5040805c78d2ba1d75e7a693f6f9d9a47657581", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00007__wfv__styles-image-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-image-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "styles-image-final-dot", "sha256": "5c3a4d3865ac989ba85e50659b464dd5256a15000c0617c96c7b915f0feb0b0a", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00008__wfv__styles-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "styles-image-final-dot", "sha256": "5c3a4d3865ac989ba85e50659b464dd5256a15000c0617c96c7b915f0feb0b0a", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00008__wfv__styles-image-final-dot.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-image-final-dot_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 1, "name": "s80a-control-minimal-end", "sha256": "03ca5c8ed7b05c1932d5aa5a37dcdc71e5f9f7e410f4961bd8439b9e1647b194", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:27+00:00", "staged": "00005__wfv__s80a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s80a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s80a", "pass": 2, "name": "s80a-control-minimal-end", "sha256": "03ca5c8ed7b05c1932d5aa5a37dcdc71e5f9f7e410f4961bd8439b9e1647b194", "validatorRevision": "2686b56714cb94a8c796fd0d033474e0f661a381", "observedAt": "2026-10-28T00:30:38+00:00", "staged": "00005__wfv__s80a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s80a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 80 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s80builder.mts`:

```ts
// Session 80 (2026-10-28): which relationships parts besides `_rels/.rels` and a story root's own sidecar does Word read
// when it checks their targets (#987)? Session 79 opened clean a folder target and an absent escaping customXml target
// in the sidecar of a part nothing references, while the same folder target in the main document's sidecar got the
// recovery offer (as in session 72). The read model lists only the story roots' sidecars; a used header's sidecar, an
// unused header's and the styles part's are unprobed for these targets.
// s80a: a header word/header1.xml holding Head, referenced by the section (used), whose sidecar
// word/_rels/header1.xml.rels relates the stored unused word/media/image1.png by media/image1.png (calibration) and
// media/image1.png/., an absent media/missing.png (calibration) and an absent ../customXml/item1.xml; the same header
// related but not referenced (unused) with media/image1.png/. in its sidecar; and the styles part's sidecar
// word/_rels/styles.xml.rels relating the image by media/image1.png (calibration) and media/image1.png/.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's,
// the image helper s72builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825), and its src (#985).
// Run from a worktree root: CHUNK=s80a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const withPng = (ct: string) => replaceOnce(ct, "</Types>", '<Default Extension="png" ContentType="image/png"/></Types>');

const PNG = Uint8Array.from(
    Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "base64"),
);
const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const HEADER = "word/header1.xml";
const HEADER_SIDECAR = "word/_rels/header1.xml.rels";
const STYLES_SIDECAR = "word/_rels/styles.xml.rels";
const withHeaderOverride = (ct: string) =>
    replaceOnce(ct, "</Types>", `<Override PartName="/${HEADER}" ContentType="${WML}.header+xml"/></Types>`);
const sidecarHolding = (rel: string) => `${XML_DECL}<Relationships xmlns="${PR}">${rel}</Relationships>`;
/** The main document with its section referencing the header relationship rIdH. */
const MAIN_USING_HEADER = replaceOnce(
    replaceOnce(P["word/document.xml"]!, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${R}"`),
    "<w:sectPr>",
    '<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>',
);
/**
 * The minimal parts with word/media/image1.png stored and word/header1.xml holding "Head", related from the main
 * document's sidecar as rIdH and referenced by the section when `used`, whose own sidecar holds `rel`.
 */
const headerSidecar = (rel: string, used: boolean): Record<string, string | Uint8Array> => ({
    ...P,
    "word/document.xml": used ? MAIN_USING_HEADER : P["word/document.xml"]!,
    "word/media/image1.png": PNG,
    [HEADER]: `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Head</w:t></w:r></w:p></w:hdr>`,
    [HEADER_SIDECAR]: sidecarHolding(rel),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
    [CT]: withHeaderOverride(withPng(P[CT]!)),
});
/** The minimal parts with word/media/image1.png stored, and the styles part's sidecar holding `rel`. */
const stylesSidecar = (rel: string): Record<string, string | Uint8Array> => ({
    ...P,
    "word/media/image1.png": PNG,
    [STYLES_SIDECAR]: sidecarHolding(rel),
    [CT]: withPng(P[CT]!),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s80a: withControls("s80a", [
        [
            "header-used-image-calibration",
            "calibration: a used word/header1.xml whose sidecar relates the stored unused word/media/image1.png by media/image1.png",
            () => buildDocx(headerSidecar(relationship("rId1", "image", "media/image1.png"), true)),
        ],
        [
            "header-used-image-final-dot",
            "#987: the used header's sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)",
            () => buildDocx(headerSidecar(relationship("rId1", "image", "media/image1.png/."), true)),
        ],
        [
            "header-used-image-missing-calibration",
            "calibration: the used header's sidecar relates an absent media/missing.png",
            () => buildDocx(headerSidecar(relationship("rId1", "image", "media/missing.png"), true)),
        ],
        [
            "header-used-customxml-escaping-absent",
            "#987: the used header's sidecar relates an absent ../customXml/item1.xml (#734's blocking shape, session 54)",
            () => buildDocx(headerSidecar(relationship("rId1", "customXml", "../customXml/item1.xml"), true)),
        ],
        [
            "header-unused-image-final-dot",
            "#987: the same header related but not referenced (unused); its sidecar relates the image by media/image1.png/.",
            () => buildDocx(headerSidecar(relationship("rId1", "image", "media/image1.png/."), false)),
        ],
        [
            "styles-image-calibration",
            "calibration: the styles part's sidecar relates the stored unused word/media/image1.png by media/image1.png",
            () => buildDocx(stylesSidecar(relationship("rId1", "image", "media/image1.png"))),
        ],
        [
            "styles-image-final-dot",
            "#987: the styles part's sidecar relates it by media/image1.png/. (a folder: word/media/image1.png/)",
            () => buildDocx(stylesSidecar(relationship("rId1", "image", "media/image1.png/."))),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen for the staging and log-check
// scripts to pick up (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-80 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s80a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s80/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-80 parts of docs/plans/evidence/word-probes-2026-10-24.md into s80/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s80a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s80/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def run_at(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return datetime.fromisoformat(row["run_at"]).astimezone(timezone.utc)
    raise KeyError(file)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            raw.append(json.dumps({"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                                   "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                                   "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                                   "pdf": row["pdf"], "evidence": row["evidence"]}, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

FOLDERS = {"header-used-image-final-dot.docx", "header-used-customxml-escaping-absent.docx",
           "header-unused-image-final-dot.docx", "styles-image-final-dot.docx"}
USED_HEADER = {"header-used-image-calibration.docx", "header-used-image-final-dot.docx",
               "header-used-image-missing-calibration.docx", "header-used-customxml-escaping-absent.docx"}
# The narrative's claims about outcomes, checked against results.json: Word opened every row clean. Word-valid, at the
# revision before #987, rejected the four rows whose sidecar holds a folder or an absent escaping customXml target.
for (label, file), r in results.items():
    assert r["outcome"] == "clean-open", (file, r)
    assert r["wordValid"] is (file not in FOLDERS), (file, r)
    assert r["validatorMatchesWord"] is (file not in FOLDERS), (file, r)
assert agreed == len(rows) == 9, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order, so
# the minimal controls opened 6th and 7th, between the header rows and the styles rows.
ORDER = {
    "s80a": ["header-unused-image-final-dot.docx", "header-used-customxml-escaping-absent.docx",
             "header-used-image-calibration.docx", "header-used-image-final-dot.docx",
             "header-used-image-missing-calibration.docx", "s80a-control-minimal-end.docx", "s80a-control-minimal.docx",
             "styles-image-calibration.docx", "styles-image-final-dot.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: the used header's "Head" above the main document's "Hello", and
# "Hello" alone where no section references the header. The unused image renders nothing.
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            text = rendered(run, file)
            assert text == ("Head Hello" if file in USED_HEADER else "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 80: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The scope of [#987](https://github.com/jandira-tech/docx-validate/issues/987). Session 79 opened clean a folder "
    "target and an absent escaping `customXml` target in the sidecar of a part nothing references, while the same folder "
    "target in the main document's sidecar got the recovery offer. Of the relationships parts, the read model lists only "
    "each story root's own sidecar, beside `_rels/.rels`; whether Word checks the targets in the sidecar of a part it "
    "does load was unprobed. One chunk: s80a stores the unused `word/media/image1.png` and a header `word/header1.xml` "
    "holding `Head`, related from the main document's sidecar and referenced by the section (used), whose sidecar "
    "`word/_rels/header1.xml.rels` relates the image by `media/image1.png` (calibration) and by `media/image1.png/.`, an "
    "absent `media/missing.png` (calibration) and an absent `../customXml/item1.xml`; the same header related but not "
    "referenced (unused) with `media/image1.png/.` in its sidecar; and the styles part's sidecar "
    "`word/_rels/styles.xml.rels` relating the image by `media/image1.png` (calibration) and by `media/image1.png/.`. It "
    "ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own "
    "Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs "
    f"and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are "
    "the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the "
    f"validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order, so the minimal controls opened 6th and 7th, between the header rows and the "
    "styles rows. Every row opened clean. Every used-header row's PDF holds `Head Hello`, so Word loaded the header, and "
    "every other row's holds `Hello` (`pdftotext`, both runs).",
    "",
    "- **The sidecar of a part Word loads.** In the used header's sidecar, `media/image1.png/.` and the absent "
    "`../customXml/item1.xml` open as cleanly as the calibrations, and the header renders: Word loaded the header but did "
    "not check its relationships' targets. So do `media/image1.png/.` in the unused header's sidecar and in the styles "
    "part's.",
    "",
    "With sessions 70 to 73 and 79, Word refused these targets only in `_rels/.rels` and in the main document's own "
    "relationships part. "
    f"Word-valid at {at} rejects the four rows with `rels-broken`, four false rejections, and matches Word on {matches} of "
    f"{len(rows)} rows; [#987](https://github.com/jandira-tech/docx-validate/issues/987) gates the block to the "
    "relationships parts the read model lists.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 80</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 80 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s80builder.mts", ROOT / "s80builder.mts", "ts"), ("compare.py", ROOT / "s80/compare.py", "python"),
                         ("section.py", ROOT / "s80/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s80/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed")
`````

</details>

### Session 81: 01:04Z–01:15Z on 2026-10-28, validator columns at cf1a2990

The blocks [#996](https://github.com/jandira-tech/docx-validate/issues/996) asked about. Since #986 every read-model walk stops a target climbing past the package root at the root, as Word reads it (sessions 74 to 78), so four checks began reading a part named by such a target that they had not read before: the content-type checks, the XML syntax check, and `word-shared-story-part`. Whether Word then refuses the part for the reason it refuses the in-package twin was unprobed. Chunk s81a stores a footer holding `Foot` at `/footer1.xml`, named from `word/` by `../../footer1.xml` and referenced by the section, typed footer (calibration) and typed styles by its Override (E1); `docProps/core.xml` named from `_rels/.rels` by `../docProps/core.xml`, well-formed (calibration) and with its root unclosed (F1); the styles part stored at `/styles.xml` and named from `word/` by `../../styles.xml`, well-formed (calibration, session 75's reading) and with its root unclosed (G1); `word/footnotes.xml` used by the body and by a glossary reached by `../../word/glossary/document.xml` whose sidecar relates it by `../footnotes.xml` (I2), and the same glossary using no note (calibration); the glossary reached by `glossary/document.xml` relating the notes by `../../../word/footnotes.xml`, both roots using footnote 1 (I2'); and a repeat of session 67's in-package shared notes row. Chunk s81b rebuilt I2' and the repeat and ran them again, as one run of each was lost in s81a (below): the same parts, byte for byte, in the same order, though the archives' hashes differ, as JSZip stamps each entry with its build time. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 14 of 16 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`cf1a299061fa2cbf1657a62dba2605eb7ba2f583`).

The driver opens files in name order. In s81a, the first run lost the repeat and the second run lost I2' to an AppleEvent timeout (`Microsoft Word got an error: AppleEvent timed out.`, no log evidence and no PDF), so those two rows are `unknown` there, though each of their three other readings was the recovery offer; s81b ran both twice and every reading was the recovery offer. Every calibration and control opened clean. The footer calibration's PDF holds `Hello Foot`, so Word read the footer at the root; the notes calibration's holds `Hello1 Note`, the body's note; every other clean row's holds `Hello` (`pdftotext`, both runs). No refused row left a PDF.

- **A read footer typed styles (E1).** Word offered recovery, as session 53 did for the in-package twin, and opened the footer-typed calibration clean, rendering `Foot`.
- **An unclosed part read at the root (F1, G1).** Word offered recovery for the unclosed core properties part and the unclosed root styles part, as for an in-package malformed part (#409; session 15), and opened both well-formed calibrations clean.
- **A notes part both roots use through a climbing target (I2, I2').** Word offered recovery whether the glossary was reached, or related the notes part, by a climbing target, as session 67 did in-package (its repeat here was refused too), and opened clean the climbing glossary that uses no note.

Word-valid at cf1a2990 rejects each refused row with the finding #996 asked about — `word-part-content-type-mismatch` at `footer1.xml`, `xml-syntax` at `docProps/core.xml` and at `styles.xml`, `word-shared-story-part` at `word/footnotes.xml` — and accepts every calibration, so it matches Word on 14 of 16 rows, every row whose readings agree. [#996](https://github.com/jandira-tech/docx-validate/issues/996) pins these rows in each check's tests.

| Run    | Observed             | Specimen                           | Shape                                                                                                                                                    | SHA-256 (first 16) | Word, run 1                    | Word, run 2                    | Outcome                    | word-valid at cf1a2990                     | strict at cf1a2990                                                                    |
| ------ | -------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------------ | ------------------------------ | -------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| `s81a` | 01:04:05Z, 01:12:35Z | `s81a-control-minimal`             | control                                                                                                                                                  | `db873b3122407df6` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |
| `s81a` | 01:04:05Z, 01:12:35Z | `footer-climb-calibration`         | calibration: a footer holding Foot stored at /footer1.xml, named from word/ by ../../footer1.xml, referenced by the section, typed footer                | `8da303f798db0caf` | clean-open                     | clean-open                     | clean-open                 | valid                                      | invalid: `paraid-missing-element`                                                     |
| `s81a` | 01:04:05Z, 01:12:35Z | `footer-climb-typed-styles`        | #996 E1: the same footer typed styles by its Override                                                                                                    | `b0ea119570050923` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `word-part-content-type-mismatch` | invalid: `word-part-content-type-mismatch`, `paraid-missing-element`                  |
| `s81a` | 01:04:05Z, 01:12:35Z | `core-climb-calibration`           | calibration: docProps/core.xml named from _rels/.rels by ../docProps/core.xml                                                                            | `afaaa66854d74041` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |
| `s81a` | 01:04:05Z, 01:12:35Z | `core-climb-unclosed`              | #996 F1: the same core properties part with its root unclosed                                                                                            | `597c6b99ebf316af` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `xml-syntax`                      | invalid: `xml-syntax`                                                                 |
| `s81a` | 01:04:05Z, 01:12:35Z | `styles-climb-calibration`         | calibration: the styles part stored at /styles.xml, named from word/ by ../../styles.xml (session 75's reading)                                          | `32bcec9255bf2a77` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |
| `s81a` | 01:04:05Z, 01:12:35Z | `styles-climb-unclosed`            | #996 G1: the same root styles part with its root unclosed                                                                                                | `bd1db9b392d79664` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `xml-syntax`                      | invalid: `xml-syntax`                                                                 |
| `s81a` | 01:04:05Z, 01:12:35Z | `notes-glossary-climb-shared`      | #996 I2: word/footnotes.xml used by the body and by a glossary reached by ../../word/glossary/document.xml, whose sidecar relates it by ../footnotes.xml | `21c9b255399f6596` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `word-shared-story-part`          | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-shared-story-part` |
| `s81a` | 01:04:05Z, 01:12:35Z | `notes-glossary-climb-calibration` | calibration: the same, the glossary's docPart referencing no note                                                                                        | `3aa08384b4dd2ad4` | clean-open                     | clean-open                     | clean-open                 | valid                                      | invalid: `paraid-missing-element`, `paraid-missing-element`                           |
| `s81a` | 01:04:05Z, 01:12:35Z | `notes-climb-shared`               | #996 I2': the glossary reached by glossary/document.xml, its sidecar relating the notes by ../../../word/footnotes.xml; both use footnote 1              | `06720c45142bacae` | repair-warning                 | log: no-evidence; table: other | unknown                    | invalid: `word-shared-story-part`          | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-shared-story-part` |
| `s81a` | 01:04:05Z, 01:12:35Z | `notes-shared-repeat`              | repeat of s67a: the glossary reached by glossary/document.xml, its sidecar relating the notes by ../footnotes.xml; both use footnote 1                   | `6e587f631e4f6f51` | log: no-evidence; table: other | repair-warning                 | unknown                    | invalid: `word-shared-story-part`          | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-shared-story-part` |
| `s81a` | 01:04:05Z, 01:12:35Z | `s81a-control-minimal-end`         | control                                                                                                                                                  | `edcbf1125bafbc1c` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |
| `s81b` | 01:14:30Z, 01:15:59Z | `s81b-control-minimal`             | control                                                                                                                                                  | `51a47cf8aa71bae0` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |
| `s81b` | 01:14:30Z, 01:15:59Z | `notes-climb-shared`               | #996 I2': the glossary reached by glossary/document.xml, its sidecar relating the notes by ../../../word/footnotes.xml; both use footnote 1              | `19bb014e0e4cd9f8` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `word-shared-story-part`          | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-shared-story-part` |
| `s81b` | 01:14:30Z, 01:15:59Z | `notes-shared-repeat`              | repeat of s67a: the glossary reached by glossary/document.xml, its sidecar relating the notes by ../footnotes.xml; both use footnote 1                   | `46101ae0c976cc52` | repair-warning                 | repair-warning                 | unreadable-content-warning | invalid: `word-shared-story-part`          | invalid: `paraid-missing-element`, `paraid-missing-element`, `word-shared-story-part` |
| `s81b` | 01:14:30Z, 01:15:59Z | `s81b-control-minimal-end`         | control                                                                                                                                                  | `51a47cf8aa71bae0` | clean-open                     | clean-open                     | clean-open                 | valid                                      | valid                                                                                 |

<details><summary>Raw records, session 81</summary>

```jsonl
{"run": "s81a", "pass": 1, "name": "s81a-control-minimal", "sha256": "db873b3122407df64523ed4078d04b8d0736b4f03b8c57582c7ff02eb1879534", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00009__wfv__s81a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "s81a-control-minimal", "sha256": "db873b3122407df64523ed4078d04b8d0736b4f03b8c57582c7ff02eb1879534", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00009__wfv__s81a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 1, "name": "footer-climb-calibration", "sha256": "8da303f798db0caf205a0ec69ada7014b66a00fac31134f134de45c309a1cabf", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00002__wfv__footer-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-climb-calibration_byword.pdf (14303 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "footer-climb-calibration", "sha256": "8da303f798db0caf205a0ec69ada7014b66a00fac31134f134de45c309a1cabf", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00002__wfv__footer-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-climb-calibration_byword.pdf (14303 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 1, "name": "footer-climb-typed-styles", "sha256": "b0ea119570050923a0b5f0d79d6c5f423fd1de15e4064110b6b7179911bfb58a", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00003__wfv__footer-climb-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:57:37.967 \"Word found unreadable content in 00003__wfv__footer-climb-typed-styles.docx. Do you want to recover … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__footer-climb-typed-styles.docx; refusing to guess"}
{"run": "s81a", "pass": 2, "name": "footer-climb-typed-styles", "sha256": "b0ea119570050923a0b5f0d79d6c5f423fd1de15e4064110b6b7179911bfb58a", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00003__wfv__footer-climb-typed-styles.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:04:58.573 \"Word found unreadable content in 00003__wfv__footer-climb-typed-styles.docx. Do you want to recover … ? If you trust the source of this document, click Yes.\"", "2026-10-27 21:04:58.574 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__footer-climb-typed-styles...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__footer-climb-typed-styles.docx; refusing to guess"}
{"run": "s81a", "pass": 1, "name": "core-climb-calibration", "sha256": "afaaa66854d74041cf8bd06380e89e39c94bb6ecc290ca0f506fe98eef858faf", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00000__wfv__core-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF core-climb-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "core-climb-calibration", "sha256": "afaaa66854d74041cf8bd06380e89e39c94bb6ecc290ca0f506fe98eef858faf", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00000__wfv__core-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF core-climb-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 1, "name": "core-climb-unclosed", "sha256": "597c6b99ebf316af221396102060df085bbb979ecaa66011f435ce564b8c7707", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00001__wfv__core-climb-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:57:26.137 \"Word found unreadable content in 00001__wfv__core-climb-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__core-climb-unclosed.docx; refusing to guess"}
{"run": "s81a", "pass": 2, "name": "core-climb-unclosed", "sha256": "597c6b99ebf316af221396102060df085bbb979ecaa66011f435ce564b8c7707", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00001__wfv__core-climb-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:04:40.402 'Word found unreadable content in 00001__wfv__core-climb-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'"], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__core-climb-unclosed.docx; refusing to guess"}
{"run": "s81a", "pass": 1, "name": "styles-climb-calibration", "sha256": "32bcec9255bf2a7773361067f6a2b5c47f3c78eb2989aaecf227800e1efecd00", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00010__wfv__styles-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-climb-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "styles-climb-calibration", "sha256": "32bcec9255bf2a7773361067f6a2b5c47f3c78eb2989aaecf227800e1efecd00", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00010__wfv__styles-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-climb-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 1, "name": "styles-climb-unclosed", "sha256": "bd1db9b392d7966447c09eb2317c54d3b187bafe511425b3251531732eaf887d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00011__wfv__styles-climb-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:04:01.516 'Word found unreadable content in 00011__wfv__styles-climb-unclosed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-27 21:04:02.599 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00011__wfv__styles-climb-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s81a", "pass": 2, "name": "styles-climb-unclosed", "sha256": "bd1db9b392d7966447c09eb2317c54d3b187bafe511425b3251531732eaf887d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00011__wfv__styles-climb-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:10:06.388 'Word found unreadable content in 00011__wfv__styles-climb-unclosed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-27 21:10:15.498 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00011__wfv__styles-climb-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00011__wfv__styles-climb-unclosed.docx; refusing to guess"}
{"run": "s81a", "pass": 1, "name": "notes-glossary-climb-shared", "sha256": "21c9b255399f65967602b1544627a77c8c75bbde7298d8bc6ed87f53dfa809fe", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00006__wfv__notes-glossary-climb-shared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:59:05.099 \"Word found unreadable content in 00006__wfv__notes-glossary-climb-shared.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__notes-glossary-climb-shared.docx; refusing to guess"}
{"run": "s81a", "pass": 2, "name": "notes-glossary-climb-shared", "sha256": "21c9b255399f65967602b1544627a77c8c75bbde7298d8bc6ed87f53dfa809fe", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00006__wfv__notes-glossary-climb-shared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:10:42.825 \"Word found unreadable content in 00006__wfv__notes-glossary-climb-shared.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__notes-glossary-climb-shared.docx; refusing to guess"}
{"run": "s81a", "pass": 1, "name": "notes-glossary-climb-calibration", "sha256": "3aa08384b4dd2ad4e4812c4d54d25bbd49d1c747e257defe75016d729a4ce9e2", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00005__wfv__notes-glossary-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-glossary-climb-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "notes-glossary-climb-calibration", "sha256": "3aa08384b4dd2ad4e4812c4d54d25bbd49d1c747e257defe75016d729a4ce9e2", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00005__wfv__notes-glossary-climb-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF notes-glossary-climb-calibration_byword.pdf (14684 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 1, "name": "notes-climb-shared", "sha256": "06720c45142bacaeb1f7499cedf1cb675a1232e3b1cce04b1dc97b48e82cc7eb", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00004__wfv__notes-climb-shared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 20:58:35.182 Microsoft Word, Word found unreadable content in 00004__wfv__notes-climb-shared.docx. Do you want to … t? If you trust the source of this document, click Yes.", "2026-10-27 20:58:46.241 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00004__wfv__notes-climb-shared.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s81a", "pass": 2, "name": "notes-climb-shared", "sha256": "06720c45142bacaeb1f7499cedf1cb675a1232e3b1cce04b1dc97b48e82cc7eb", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00004__wfv__notes-climb-shared.docx", "logVerdict": "no-evidence", "tableVerdict": "other", "pdf": false, "evidence": [], "error": "Microsoft Word got an error: AppleEvent timed out."}
{"run": "s81a", "pass": 1, "name": "notes-shared-repeat", "sha256": "6e587f631e4f6f511b0756b9faecb66f5b315cbcffb28279fd78402c8347ac3d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00007__wfv__notes-shared-repeat.docx", "logVerdict": "no-evidence", "tableVerdict": "other", "pdf": false, "evidence": [], "error": "Microsoft Word got an error: AppleEvent timed out."}
{"run": "s81a", "pass": 2, "name": "notes-shared-repeat", "sha256": "6e587f631e4f6f511b0756b9faecb66f5b315cbcffb28279fd78402c8347ac3d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00007__wfv__notes-shared-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:12:35.832 \"Word found unreadable content in 00007__wfv__notes-shared-repeat.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__notes-shared-repeat.docx; refusing to guess"}
{"run": "s81a", "pass": 1, "name": "s81a-control-minimal-end", "sha256": "edcbf1125bafbc1c820f98f43e02279ca373201f20c6a74b65fa5707e4e0b98c", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:04:05+00:00", "staged": "00008__wfv__s81a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81a", "pass": 2, "name": "s81a-control-minimal-end", "sha256": "edcbf1125bafbc1c820f98f43e02279ca373201f20c6a74b65fa5707e4e0b98c", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:12:35+00:00", "staged": "00008__wfv__s81a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81b", "pass": 1, "name": "s81b-control-minimal", "sha256": "51a47cf8aa71bae0b68a84f961e57ea19feee999b1c4e9467e733a0d1c84868d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:14:30+00:00", "staged": "00003__wfv__s81b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81b", "pass": 2, "name": "s81b-control-minimal", "sha256": "51a47cf8aa71bae0b68a84f961e57ea19feee999b1c4e9467e733a0d1c84868d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:15:59+00:00", "staged": "00003__wfv__s81b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81b", "pass": 1, "name": "notes-climb-shared", "sha256": "19bb014e0e4cd9f87ed466833787c84817159210be097f9bf595c7fa4d4b355f", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:14:30+00:00", "staged": "00000__wfv__notes-climb-shared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:13:25.076 'Word found unreadable content in 00000__wfv__notes-climb-shared.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-27 21:13:25.841 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00000__wfv__notes-climb-shared.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__notes-climb-shared.docx; refusing to guess"}
{"run": "s81b", "pass": 2, "name": "notes-climb-shared", "sha256": "19bb014e0e4cd9f87ed466833787c84817159210be097f9bf595c7fa4d4b355f", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:15:59+00:00", "staged": "00000__wfv__notes-climb-shared.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:14:57.273 'Word found unreadable content in 00000__wfv__notes-climb-shared.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-27 21:14:58.209 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00000__wfv__notes-climb-shared.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__notes-climb-shared.docx; refusing to guess"}
{"run": "s81b", "pass": 1, "name": "notes-shared-repeat", "sha256": "46101ae0c976cc52865dbc17b4e613e4a302d7337eaffe4acefb444aee26ff32", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:14:30+00:00", "staged": "00001__wfv__notes-shared-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:14:19.565 Microsoft Word, Word found unreadable content in 00001__wfv__notes-shared-repeat.docx. Do you want t … t? If you trust the source of this document, click Yes.", "2026-10-27 21:14:28.275 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00001__wfv__notes-shared-repeat.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s81b", "pass": 2, "name": "notes-shared-repeat", "sha256": "46101ae0c976cc52865dbc17b4e613e4a302d7337eaffe4acefb444aee26ff32", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:15:59+00:00", "staged": "00001__wfv__notes-shared-repeat.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-27 21:15:50.181 Microsoft Word, Word found unreadable content in 00001__wfv__notes-shared-repeat.docx. Do you want t … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s81b", "pass": 1, "name": "s81b-control-minimal-end", "sha256": "51a47cf8aa71bae0b68a84f961e57ea19feee999b1c4e9467e733a0d1c84868d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:14:30+00:00", "staged": "00002__wfv__s81b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s81b", "pass": 2, "name": "s81b-control-minimal-end", "sha256": "51a47cf8aa71bae0b68a84f961e57ea19feee999b1c4e9467e733a0d1c84868d", "validatorRevision": "cf1a299061fa2cbf1657a62dba2605eb7ba2f583", "observedAt": "2026-10-28T01:15:59+00:00", "staged": "00002__wfv__s81b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s81b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 81 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s81builder.mts`:

```ts
// Session 81 (2026-10-28): four word-valid blocks a climbing target reaches since #986 (#996, review 285 finding 3).
// Since 57df0b9a every read-model walk stops a climb past the package root at the root, as Word read notes, styles,
// header, customXml, comments and officeDocument climbs (sessions 74 to 78). Four consumers then judge parts no Word
// session has shown reached by a climb: a read footer typed styles (session 53 refused the in-package twin), a malformed
// core properties part (#409), a malformed eagerly read styles part (session 15) and a notes part a main document and a
// reached glossary both use (session 67).
// s81a: a footer holding Foot stored at /footer1.xml, named from word/ by ../../footer1.xml and referenced by the section,
// typed footer (calibration) and styles; docProps/core.xml named from _rels/.rels by ../docProps/core.xml, well-formed
// (calibration) and unclosed; a root styles.xml named from word/ by ../../styles.xml, well-formed (calibration) and
// unclosed; and word/footnotes.xml (footnote 1) that the main document relates and references, with a glossary
// word/glossary/document.xml whose sidecar relates the same notes part: the glossary reached by
// ../../word/glossary/document.xml with the notes by ../footnotes.xml (its docPart referencing footnote 1, and, as a
// calibration, referencing nothing), the glossary reached in-package with the notes by ../../../word/footnotes.xml, and
// session 67's in-package row repeated.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s67builder.mts's,
// the glossary s67builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825), and its src (#985).
// Run from a worktree root: CHUNK=s81a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const MAIN = P["word/document.xml"]!;
const overrides = (ct: string, ...pairs: [string, string][]) =>
    pairs.reduce(
        (types, [part, type]) => replaceOnce(types, "</Types>", `<Override PartName="/${part}" ContentType="${type}"/></Types>`),
        ct,
    );
const withR = (doc: string) => replaceOnce(doc, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${R}"`);

/** A footer holding Foot stored at /footer1.xml, named from word/ by ../../footer1.xml, referenced by the section, typed `type`. */
const climbingFooter = (type: string): Record<string, string> => ({
    ...P,
    "word/document.xml": replaceOnce(withR(MAIN), "<w:sectPr>", '<w:sectPr><w:footerReference w:type="default" r:id="rIdF"/>'),
    "footer1.xml": `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Foot</w:t></w:r></w:p></w:ftr>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdF", "footer", "../../footer1.xml")),
    [CT]: overrides(P[CT]!, ["footer1.xml", type]),
});

const CORE_RELATIONSHIP = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
const CORE_OPEN = `${XML_DECL}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>S81</dc:title>`;
/** docProps/core.xml holding `core`, named from _rels/.rels by ../docProps/core.xml. */
const climbingCore = (core: string): Record<string, string> => ({
    ...P,
    "_rels/.rels": appendRels(P["_rels/.rels"]!, `<Relationship Id="rIdP" Type="${CORE_RELATIONSHIP}" Target="../docProps/core.xml"/>`),
    "docProps/core.xml": core,
    [CT]: overrides(P[CT]!, ["docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"]),
});

/** The styles part moved to the root as /styles.xml holding `styles`, named from word/ by ../../styles.xml. */
const climbingStyles = (styles: string): Record<string, string> => {
    const parts: Record<string, string> = {
        ...P,
        "styles.xml": styles,
        [SIDECAR]: replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', 'Target="../../styles.xml"'),
        [CT]: replaceOnce(P[CT]!, 'PartName="/word/styles.xml"', 'PartName="/styles.xml"'),
    };
    delete parts["word/styles.xml"];
    return parts;
};
const STYLES_UNCLOSED = replaceOnce(P["word/styles.xml"]!, "</w:styles>", "");

const NOTE_REF = '<w:r><w:footnoteReference w:id="1"/></w:r>';
const glossaryXml = (usesNote: boolean) =>
    `${XML_DECL}<w:glossaryDocument xmlns:w="${W}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody><w:p><w:r><w:t>Text</w:t></w:r>${usesNote ? NOTE_REF : ""}</w:p></w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/**
 * word/footnotes.xml holding footnote 1, which the main document relates by footnotes.xml and references, and a glossary
 * word/glossary/document.xml the main document relates by `glossaryTarget`, whose sidecar relates the same notes part
 * by `notesTarget`; the glossary's docPart references footnote 1 when `glossaryUsesNote`.
 */
const sharedNotes = (glossaryTarget: string, notesTarget: string, glossaryUsesNote: boolean): Record<string, string> => ({
    ...P,
    "word/document.xml": replaceOnce(MAIN, "<w:r><w:t>Hello</w:t></w:r>", `<w:r><w:t>Hello</w:t></w:r>${NOTE_REF}`),
    "word/footnotes.xml": `${XML_DECL}<w:footnotes xmlns:w="${W}"><w:footnote w:id="1"><w:p><w:r><w:t>Note</w:t></w:r></w:p></w:footnote></w:footnotes>`,
    "word/glossary/document.xml": glossaryXml(glossaryUsesNote),
    "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="${PR}">${relationship("rId1", "footnotes", notesTarget)}</Relationships>`,
    [SIDECAR]: appendRels(
        P[SIDECAR]!,
        relationship("rIdN", "footnotes", "footnotes.xml") + relationship("rIdG", "glossaryDocument", glossaryTarget),
    ),
    [CT]: overrides(P[CT]!, ["word/footnotes.xml", `${WML}.footnotes+xml`], ["word/glossary/document.xml", `${WML}.document.glossary+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s81a: withControls("s81a", [
        [
            "footer-climb-calibration",
            "calibration: a footer holding Foot stored at /footer1.xml, named from word/ by ../../footer1.xml, referenced by the section, typed footer",
            () => buildDocx(climbingFooter(`${WML}.footer+xml`)),
        ],
        [
            "footer-climb-typed-styles",
            "#996 E1: the same footer typed styles by its Override",
            () => buildDocx(climbingFooter(`${WML}.styles+xml`)),
        ],
        [
            "core-climb-calibration",
            "calibration: docProps/core.xml named from _rels/.rels by ../docProps/core.xml",
            () => buildDocx(climbingCore(`${CORE_OPEN}</cp:coreProperties>`)),
        ],
        ["core-climb-unclosed", "#996 F1: the same core properties part with its root unclosed", () => buildDocx(climbingCore(CORE_OPEN))],
        [
            "styles-climb-calibration",
            "calibration: the styles part stored at /styles.xml, named from word/ by ../../styles.xml (session 75's reading)",
            () => buildDocx(climbingStyles(P["word/styles.xml"]!)),
        ],
        [
            "styles-climb-unclosed",
            "#996 G1: the same root styles part with its root unclosed",
            () => buildDocx(climbingStyles(STYLES_UNCLOSED)),
        ],
        [
            "notes-glossary-climb-shared",
            "#996 I2: word/footnotes.xml used by the body and by a glossary reached by ../../word/glossary/document.xml, whose sidecar relates it by ../footnotes.xml",
            () => buildDocx(sharedNotes("../../word/glossary/document.xml", "../footnotes.xml", true)),
        ],
        [
            "notes-glossary-climb-calibration",
            "calibration: the same, the glossary's docPart referencing no note",
            () => buildDocx(sharedNotes("../../word/glossary/document.xml", "../footnotes.xml", false)),
        ],
        [
            "notes-climb-shared",
            "#996 I2': the glossary reached by glossary/document.xml, its sidecar relating the notes by ../../../word/footnotes.xml; both use footnote 1",
            () => buildDocx(sharedNotes("glossary/document.xml", "../../../word/footnotes.xml", true)),
        ],
        [
            "notes-shared-repeat",
            "repeat of s67a: the glossary reached by glossary/document.xml, its sidecar relating the notes by ../footnotes.xml; both use footnote 1",
            () => buildDocx(sharedNotes("glossary/document.xml", "../footnotes.xml", true)),
        ],
    ]),
    // s81a's notes-climb-shared (run 2) and notes-shared-repeat (run 1) each had one run with no Word evidence (an
    // AppleEvent timeout); s81b runs the two rows again, twice.
    s81b: withControls("s81b", [
        [
            "notes-climb-shared",
            "#996 I2': the glossary reached by glossary/document.xml, its sidecar relating the notes by ../../../word/footnotes.xml; both use footnote 1",
            () => buildDocx(sharedNotes("glossary/document.xml", "../../../word/footnotes.xml", true)),
        ],
        [
            "notes-shared-repeat",
            "repeat of s67a: the glossary reached by glossary/document.xml, its sidecar relating the notes by ../footnotes.xml; both use footnote 1",
            () => buildDocx(sharedNotes("glossary/document.xml", "../footnotes.xml", true)),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen for the staging and log-check
// scripts to pick up (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-81 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s81a", "s81b")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s81/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-81 parts of docs/plans/evidence/word-probes-2026-10-24.md into s81/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
import zipfile
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s81a", "s81b")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s81/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            record = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                      "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                      "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                      "pdf": row["pdf"], "evidence": row["evidence"]}
            error = manifest(r, s["file"]).get("error")
            if error:
                record["error"] = error
            raw.append(json.dumps(record, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"footer-climb-typed-styles.docx", "core-climb-unclosed.docx", "styles-climb-unclosed.docx",
           "notes-glossary-climb-shared.docx", "notes-climb-shared.docx", "notes-shared-repeat.docx"}
# The two s81a rows a run lost to an AppleEvent timeout, which s81b settles.
LOST = {("s81a", "notes-climb-shared.docx"): 2, ("s81a", "notes-shared-repeat.docx"): 1}
# The narrative's claims about outcomes, checked against results.json: every reading Word gave of the refused rows was
# the recovery offer, and every other row opened clean; word-valid at the probed revision rejects exactly the refused
# rows, so it matches Word on every row whose readings agree.
for (label, file), r in results.items():
    lost = LOST.get((label, file))
    readings = [x for i, x in enumerate(r["readings"]) if lost is None or i // 2 != lost - 1]
    if lost is None:
        assert r["agreed"], (label, file, r)
    else:
        assert not r["agreed"] and r["outcome"] == "unknown", (label, file, r)
        assert r["readings"][2 * (lost - 1):2 * lost] == ["no-evidence", "other"], (label, file, r)
    assert set(readings) == ({"repair-warning"} if file in REFUSED else {"clean-open"}), (label, file, r)
    assert r["wordValid"] is (file not in REFUSED), (label, file, r)
    assert r["validatorMatchesWord"] is (lost is None), (label, file, r)
for label, file in LOST:
    assert results[("s81b", file)]["agreed"] and results[("s81b", file)]["outcome"] == "unreadable-content-warning", file
    # s81b rebuilt the row: the same part names and part bytes as s81a's, in the same order. The archives' hashes
    # differ, as JSZip stamps each entry with its build time.
    stored = []
    for chunk in ("s81a", "s81b"):
        with zipfile.ZipFile(ROOT / chunk / "src" / file) as z:
            stored.append([(i.filename, z.read(i)) for i in z.infolist()])
    assert stored[0] == stored[1], file
assert agreed == len(rows) - len(LOST) == 14, (agreed, len(rows))
# Where each run opened each row, from the driver's manifests (in open order, #671). The driver opens in name order.
ORDER = {
    "s81a": ["core-climb-calibration.docx", "core-climb-unclosed.docx", "footer-climb-calibration.docx",
             "footer-climb-typed-styles.docx", "notes-climb-shared.docx", "notes-glossary-climb-calibration.docx",
             "notes-glossary-climb-shared.docx", "notes-shared-repeat.docx", "s81a-control-minimal-end.docx",
             "s81a-control-minimal.docx", "styles-climb-calibration.docx", "styles-climb-unclosed.docx"],
    "s81b": ["notes-climb-shared.docx", "notes-shared-repeat.docx", "s81b-control-minimal-end.docx",
             "s81b-control-minimal.docx"],
}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == ORDER[label], (run, opened)
# The text Word rendered in each row, both runs: the footer's "Foot" below "Hello", the body note's "1" and "Note", and
# "Hello" alone elsewhere. A refused row, and a row a run lost, left no PDF.
RENDERED = {"footer-climb-calibration.docx": "Hello Foot", "notes-glossary-climb-calibration.docx": "Hello1 Note"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for file in ORDER[label]:
            text = rendered(run, file)
            assert text == (None if file in REFUSED else RENDERED.get(file, "Hello")), (run, file, text)
for (label, file), n in LOST.items():
    run = ROOT / label if n == 1 else ROOT / label / "pass2"
    assert manifest(run, file)["error"] == "Microsoft Word got an error: AppleEvent timed out.", (run, file)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 81: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "The blocks [#996](https://github.com/jandira-tech/docx-validate/issues/996) asked about. Since #986 every read-model "
    "walk stops a target climbing past the package root at the root, as Word reads it (sessions 74 to 78), so four checks "
    "began reading a part named by such a target that they had not read before: the content-type checks, the XML syntax "
    "check, and `word-shared-story-part`. Whether Word then refuses the part for the reason it refuses the in-package twin "
    "was unprobed. Chunk s81a stores a footer holding `Foot` at `/footer1.xml`, named from `word/` by `../../footer1.xml` "
    "and referenced by the section, typed footer (calibration) and typed styles by its Override (E1); `docProps/core.xml` "
    "named from `_rels/.rels` by `../docProps/core.xml`, well-formed (calibration) and with its root unclosed (F1); the "
    "styles part stored at `/styles.xml` and named from `word/` by `../../styles.xml`, well-formed (calibration, session "
    "75's reading) and with its root unclosed (G1); `word/footnotes.xml` used by the body and by a glossary reached by "
    "`../../word/glossary/document.xml` whose sidecar relates it by `../footnotes.xml` (I2), and the same glossary using "
    "no note (calibration); the glossary reached by `glossary/document.xml` relating the notes by "
    "`../../../word/footnotes.xml`, both roots using footnote 1 (I2'); and a repeat of session 67's in-package shared "
    "notes row. Chunk s81b rebuilt I2' and the repeat and ran them again, as one run of each was lost in s81a (below): "
    "the same parts, byte for byte, in the same order, though the archives' hashes differ, as JSZip stamps each entry "
    "with its build time. Each "
    "chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its "
    "own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both "
    f"runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in "
    "Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder "
    f"recorded the validator revision in every row (`{rev}`).",
    "",
    "The driver opens files in name order. In s81a, the first run lost the repeat and the second run lost I2' to an "
    "AppleEvent timeout (`Microsoft Word got an error: AppleEvent timed out.`, no log evidence and no PDF), so those two "
    "rows are `unknown` there, though each of their three other readings was the recovery offer; s81b ran both twice "
    "and every reading was the recovery offer. Every calibration and control opened clean. The footer calibration's PDF "
    "holds `Hello Foot`, so Word read the footer at the root; the notes calibration's holds `Hello1 Note`, the body's "
    "note; every other clean row's holds `Hello` (`pdftotext`, both runs). No refused row left a PDF.",
    "",
    "- **A read footer typed styles (E1).** Word offered recovery, as session 53 did for the in-package twin, and opened "
    "the footer-typed calibration clean, rendering `Foot`.",
    "- **An unclosed part read at the root (F1, G1).** Word offered recovery for the unclosed core properties part and "
    "the unclosed root styles part, as for an in-package malformed part (#409; session 15), and opened both well-formed "
    "calibrations clean.",
    "- **A notes part both roots use through a climbing target (I2, I2').** Word offered recovery whether the glossary "
    "was reached, or related the notes part, by a climbing target, as session 67 did in-package (its repeat here was "
    "refused too), and opened clean the climbing glossary that uses no note.",
    "",
    f"Word-valid at {at} rejects each refused row with the finding #996 asked about — "
    "`word-part-content-type-mismatch` at `footer1.xml`, `xml-syntax` at `docProps/core.xml` and at `styles.xml`, "
    "`word-shared-story-part` at `word/footnotes.xml` — and accepts every calibration, so it matches Word on "
    f"{matches} of {len(rows)} rows, every row whose readings agree. "
    "[#996](https://github.com/jandira-tech/docx-validate/issues/996) pins these rows in each check's tests.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 81</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 81 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s81builder.mts", ROOT / "s81builder.mts", "ts"), ("compare.py", ROOT / "s81/compare.py", "python"),
                         ("section.py", ROOT / "s81/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s81/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 82: 12:21Z–12:25Z on 2026-10-28, validator columns at 1661e12f

Which parts Word judges a hyperlink's relationship in ([#1106](https://github.com/jandira-tech/docx-validate/issues/1106)). `word-hyperlink-relationship` judged the parts named like a story wherever stored, not the parts Word reads. Each row holds session 28's refused shape in one placement: a `w:hyperlink` holding `Link` whose relationship has the Type `…/relationships/HYPERLINK`, TargetMode External, a URL target (s28a refused it in `word/document.xml`); its calibration uses the exact Transitional Type. Chunk s82a places it in `word/document.xml` (s28a repeated), in a main document stored as `word/main.xml`, in a used header stored as `word/header1.xml` and in a used header stored as `word/hdr.xml`. Chunk s82b places it in `word/header9.xml`, typed header by its Override, which no relationship names; in a glossary stored as `word/glossary/document.xml` that no relationship reaches; and in the same glossary reached by the main document's `glossaryDocument` relationship. Chunk s82c places it in `word/header1.xml`, which the main document relates but no section references, and in footnote 1 of `word/footnotes.xml`, which the main document relates and does not reference, then does. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 26 of 26 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`1661e12f488567cd6a8abef2403329eae336bc54`).

Every calibration and control opened clean. Word rendered `Link` where it read the part holding the hyperlink: after `Hello` in both main documents, before it in both used headers, and after the body's `Hello1` as the used note's text; every other clean row's PDF holds `Hello` alone (`pdftotext`, both runs). No refused row left a PDF.

- **Word judges the hyperlink in the parts it reads, whatever their names.** It offered recovery for the refused Type in `word/document.xml`, in the main document stored as `word/main.xml`, in both used headers, in the reached glossary and in the used footnotes part.
- **It does not judge a part it does not read.** It opened the refused Type clean in the unrelated `word/header9.xml`, in the unreached glossary, in the header no section references and in the footnotes part nothing references, as the read model says it reads none of them (session 17 for the glossary, #726 and #800 for the stories).

Word-valid at 1661e12f judged by name, so it matches Word on 20 of 26 rows: it passes the refused Type in the renamed main document and the renamed header, and rejects it in the four parts Word does not read. [#1106](https://github.com/jandira-tech/docx-validate/issues/1106) moves the rule onto the read model and pins every row in `tests/word-hyperlink-relationship.test.ts`.

| Run    | Observed             | Specimen                               | Shape                                                                                                                 | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 1661e12f                 | strict at 1661e12f                                                                    |
| ------ | -------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- |
| `s82a` | 12:21:33Z, 12:22:49Z | `s82a-control-minimal`                 | control                                                                                                               | `5ddc836d0a28a1d8` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82a` | 12:21:33Z, 12:22:49Z | `main-link-refused-type`               | #1106: s28a repeated, a hyperlink in word/document.xml whose relationship has the Type …/HYPERLINK                    | `929f15051169c551` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82a` | 12:21:33Z, 12:22:49Z | `main-link-calibration`                | calibration: the same with the exact hyperlink Type                                                                   | `e8e4272bfb9987db` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82a` | 12:21:33Z, 12:22:49Z | `renamed-main-link-refused-type`       | #1106: the same hyperlink in a main document stored as word/main.xml                                                  | `cfd6c8b2134877fa` | repair-warning | repair-warning | unreadable-content-warning | valid                                  | valid                                                                                 |
| `s82a` | 12:21:33Z, 12:22:49Z | `renamed-main-link-calibration`        | calibration: the same with the exact hyperlink Type                                                                   | `5827651f38f6d353` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82a` | 12:21:33Z, 12:22:49Z | `header1-link-refused-type`            | #1106: the same hyperlink in a used header stored as word/header1.xml                                                 | `38a88b8cab0783a0` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82a` | 12:21:33Z, 12:22:49Z | `header1-link-calibration`             | calibration: the same with the exact hyperlink Type                                                                   | `de0d5d1ac9e56e47` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82a` | 12:21:33Z, 12:22:49Z | `renamed-header-link-refused-type`     | #1106: the same hyperlink in a used header stored as word/hdr.xml                                                     | `5a7f9abc2fc1e261` | repair-warning | repair-warning | unreadable-content-warning | valid                                  | valid                                                                                 |
| `s82a` | 12:21:33Z, 12:22:49Z | `renamed-header-link-calibration`      | calibration: the same with the exact hyperlink Type                                                                   | `495ea92d63f34101` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82a` | 12:21:33Z, 12:22:49Z | `s82a-control-minimal-end`             | control                                                                                                               | `5ddc836d0a28a1d8` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82b` | 12:23:14Z, 12:23:42Z | `s82b-control-minimal`                 | control                                                                                                               | `5ddc836d0a28a1d8` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82b` | 12:23:14Z, 12:23:42Z | `unrelated-header9-link-refused-type`  | #1106: the same hyperlink in word/header9.xml, typed header, which no relationship names                              | `ec535fbd5f5eb440` | clean-open     | clean-open     | clean-open                 | invalid: `word-hyperlink-relationship` | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-hyperlink-relationship` |
| `s82b` | 12:23:14Z, 12:23:42Z | `unrelated-header9-link-calibration`   | calibration: the same with the exact hyperlink Type                                                                   | `f60243cde0f4ee6d` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `rels-unreferenced`, `paraid-missing-element`                                |
| `s82b` | 12:23:14Z, 12:23:42Z | `unreached-glossary-link-refused-type` | #1106: the same hyperlink in word/glossary/document.xml, which no relationship reaches                                | `d1eb0c6e21afaf6c` | clean-open     | clean-open     | clean-open                 | invalid: `word-hyperlink-relationship` | invalid: `rels-unreferenced`, `paraid-missing-element`, `word-hyperlink-relationship` |
| `s82b` | 12:23:14Z, 12:23:42Z | `unreached-glossary-link-calibration`  | calibration: the same with the exact hyperlink Type                                                                   | `bebd00ed81439b2f` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `rels-unreferenced`, `paraid-missing-element`                                |
| `s82b` | 12:23:14Z, 12:23:42Z | `reached-glossary-link-refused-type`   | #1106: the same hyperlink in a glossary the main document relates                                                     | `0a884513de8ab561` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82b` | 12:23:14Z, 12:23:42Z | `reached-glossary-link-calibration`    | calibration: the same with the exact hyperlink Type                                                                   | `4f2c657c2d57d183` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82b` | 12:23:14Z, 12:23:42Z | `s82b-control-minimal-end`             | control                                                                                                               | `5ddc836d0a28a1d8` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82c` | 12:25:19Z, 12:25:44Z | `s82c-control-minimal`                 | control                                                                                                               | `c8f2e5acd1898557` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |
| `s82c` | 12:25:19Z, 12:25:44Z | `unused-header1-link-refused-type`     | #1106: the same hyperlink in word/header1.xml, which the main document relates but no section references              | `0a347eea94861f59` | clean-open     | clean-open     | clean-open                 | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82c` | 12:25:19Z, 12:25:44Z | `unused-header1-link-calibration`      | calibration: the same with the exact hyperlink Type                                                                   | `561c4e4b2297aaad` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82c` | 12:25:19Z, 12:25:44Z | `unused-footnotes-link-refused-type`   | #1106: the same hyperlink in footnote 1 of word/footnotes.xml, which the main document relates but does not reference | `0aca6a4133892f17` | clean-open     | clean-open     | clean-open                 | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82c` | 12:25:19Z, 12:25:44Z | `unused-footnotes-link-calibration`    | calibration: the same with the exact hyperlink Type                                                                   | `828f7845e2d92958` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82c` | 12:25:19Z, 12:25:44Z | `used-footnotes-link-refused-type`     | #1106: the same, the body referencing footnote 1                                                                      | `18c64afcf355ec94` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-hyperlink-relationship` | invalid: `paraid-missing-element`, `word-hyperlink-relationship`                      |
| `s82c` | 12:25:19Z, 12:25:44Z | `used-footnotes-link-calibration`      | calibration: the same with the exact hyperlink Type                                                                   | `78c5a2413d032e8b` | clean-open     | clean-open     | clean-open                 | valid                                  | invalid: `paraid-missing-element`                                                     |
| `s82c` | 12:25:19Z, 12:25:44Z | `s82c-control-minimal-end`             | control                                                                                                               | `c8f2e5acd1898557` | clean-open     | clean-open     | clean-open                 | valid                                  | valid                                                                                 |

<details><summary>Raw records, session 82</summary>

```jsonl
{"run": "s82a", "pass": 1, "name": "s82a-control-minimal", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00009__wfv__s82a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "s82a-control-minimal", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00009__wfv__s82a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 1, "name": "main-link-refused-type", "sha256": "929f15051169c551ec5877d66353c46497807a0f6f9b19c9bd1ac35b0a2a7735", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00003__wfv__main-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:21:03.244 \"Word found unreadable content in 00003__wfv__main-link-refused-type.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__main-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 2, "name": "main-link-refused-type", "sha256": "929f15051169c551ec5877d66353c46497807a0f6f9b19c9bd1ac35b0a2a7735", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00003__wfv__main-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:22:19.333 \"Word found unreadable content in 00003__wfv__main-link-refused-type.docx. Do you want to recover th … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s82a", "pass": 1, "name": "main-link-calibration", "sha256": "e8e4272bfb9987db4a36641353e16173f3510ddb93f76d17c5ed2e430be08a85", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00002__wfv__main-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-link-calibration_byword.pdf (16092 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "main-link-calibration", "sha256": "e8e4272bfb9987db4a36641353e16173f3510ddb93f76d17c5ed2e430be08a85", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00002__wfv__main-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF main-link-calibration_byword.pdf (16092 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 1, "name": "renamed-main-link-refused-type", "sha256": "cfd6c8b2134877fabb02e0c0e7ba592f7cfea2d7689e48ef8458411e0917741e", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00007__wfv__renamed-main-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:21:32.440 \"Word found unreadable content in 00007__wfv__renamed-main-link-refused-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__renamed-main-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 2, "name": "renamed-main-link-refused-type", "sha256": "cfd6c8b2134877fabb02e0c0e7ba592f7cfea2d7689e48ef8458411e0917741e", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00007__wfv__renamed-main-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:22:48.568 \"Word found unreadable content in 00007__wfv__renamed-main-link-refused-type.docx. Do you want to re … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s82a", "pass": 1, "name": "renamed-main-link-calibration", "sha256": "5827651f38f6d35392f58ff1f36f927a3b60874a03c5e6d6f3715aaf244204a6", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00006__wfv__renamed-main-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-main-link-calibration_byword.pdf (16092 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "renamed-main-link-calibration", "sha256": "5827651f38f6d35392f58ff1f36f927a3b60874a03c5e6d6f3715aaf244204a6", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00006__wfv__renamed-main-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-main-link-calibration_byword.pdf (16092 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 1, "name": "header1-link-refused-type", "sha256": "38a88b8cab0783a05f0bd442ab7e32212dcf914143938f9169ded463a4128057", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00001__wfv__header1-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:20:46.064 'Word found unreadable content in 00001__wfv__header1-link-refused-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 08:20:46.906 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__header1-link-refused-type...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__header1-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 2, "name": "header1-link-refused-type", "sha256": "38a88b8cab0783a05f0bd442ab7e32212dcf914143938f9169ded463a4128057", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00001__wfv__header1-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:22:02.197 'Word found unreadable content in 00001__wfv__header1-link-refused-type.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 08:22:02.820 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__header1-link-refused-type...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__header1-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 1, "name": "header1-link-calibration", "sha256": "de0d5d1ac9e56e47722d666835b87f1ba7cb636e5ce78705a29b3e8aa77189eb", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00000__wfv__header1-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header1-link-calibration_byword.pdf (16084 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "header1-link-calibration", "sha256": "de0d5d1ac9e56e47722d666835b87f1ba7cb636e5ce78705a29b3e8aa77189eb", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00000__wfv__header1-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header1-link-calibration_byword.pdf (16084 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 1, "name": "renamed-header-link-refused-type", "sha256": "5a7f9abc2fc1e261d4fa128bc4899b8242118223902d5da9a9eb4758bfb2cb74", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00005__wfv__renamed-header-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:21:15.749 \"Word found unreadable content in 00005__wfv__renamed-header-link-refused-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__renamed-header-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 2, "name": "renamed-header-link-refused-type", "sha256": "5a7f9abc2fc1e261d4fa128bc4899b8242118223902d5da9a9eb4758bfb2cb74", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00005__wfv__renamed-header-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:22:31.868 \"Word found unreadable content in 00005__wfv__renamed-header-link-refused-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__renamed-header-link-refused-type.docx; refusing to guess"}
{"run": "s82a", "pass": 1, "name": "renamed-header-link-calibration", "sha256": "495ea92d63f34101e03061061e5fd8471304d5b38afb0eb248b528c114c390b1", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00004__wfv__renamed-header-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-header-link-calibration_byword.pdf (16084 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "renamed-header-link-calibration", "sha256": "495ea92d63f34101e03061061e5fd8471304d5b38afb0eb248b528c114c390b1", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00004__wfv__renamed-header-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF renamed-header-link-calibration_byword.pdf (16084 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 1, "name": "s82a-control-minimal-end", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:21:33+00:00", "staged": "00008__wfv__s82a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82a", "pass": 2, "name": "s82a-control-minimal-end", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:22:49+00:00", "staged": "00008__wfv__s82a-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82a-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "s82b-control-minimal", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00003__wfv__s82b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "s82b-control-minimal", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00003__wfv__s82b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "unrelated-header9-link-refused-type", "sha256": "ec535fbd5f5eb4406399303844d677b81cc4d9377b8f7e66b8f60b9b23b45937", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00007__wfv__unrelated-header9-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header9-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "unrelated-header9-link-refused-type", "sha256": "ec535fbd5f5eb4406399303844d677b81cc4d9377b8f7e66b8f60b9b23b45937", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00007__wfv__unrelated-header9-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header9-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "unrelated-header9-link-calibration", "sha256": "f60243cde0f4ee6d8b822f4b766fd36097c61f6916f20bf35c250b3178bddcda", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00006__wfv__unrelated-header9-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header9-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "unrelated-header9-link-calibration", "sha256": "f60243cde0f4ee6d8b822f4b766fd36097c61f6916f20bf35c250b3178bddcda", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00006__wfv__unrelated-header9-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unrelated-header9-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "unreached-glossary-link-refused-type", "sha256": "d1eb0c6e21afaf6c50c8b07951c2259af97ff927c5b191c95959d74caa047525", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00005__wfv__unreached-glossary-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "unreached-glossary-link-refused-type", "sha256": "d1eb0c6e21afaf6c50c8b07951c2259af97ff927c5b191c95959d74caa047525", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00005__wfv__unreached-glossary-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "unreached-glossary-link-calibration", "sha256": "bebd00ed81439b2fcf4f0ddd2e10725622a97363921691bc8a24a2047bb4ff55", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00004__wfv__unreached-glossary-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "unreached-glossary-link-calibration", "sha256": "bebd00ed81439b2fcf4f0ddd2e10725622a97363921691bc8a24a2047bb4ff55", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00004__wfv__unreached-glossary-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unreached-glossary-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "reached-glossary-link-refused-type", "sha256": "0a884513de8ab5612612f0a23f6bb123ec0f13ae1b89bd3e4bc32b7edab16b95", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00001__wfv__reached-glossary-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:23:11.734 \"Word found unreadable content in 00001__wfv__reached-glossary-link-refused-type.docx. Do you want t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s82b", "pass": 2, "name": "reached-glossary-link-refused-type", "sha256": "0a884513de8ab5612612f0a23f6bb123ec0f13ae1b89bd3e4bc32b7edab16b95", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00001__wfv__reached-glossary-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:23:40.167 \"Word found unreadable content in 00001__wfv__reached-glossary-link-refused-type.docx. Do you want t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__reached-glossary-link-refused-type.docx; refusing to guess"}
{"run": "s82b", "pass": 1, "name": "reached-glossary-link-calibration", "sha256": "4f2c657c2d57d18329fee1b31bb27a62083f3e8f1767eff03713e1b467fe150e", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00000__wfv__reached-glossary-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF reached-glossary-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "reached-glossary-link-calibration", "sha256": "4f2c657c2d57d18329fee1b31bb27a62083f3e8f1767eff03713e1b467fe150e", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00000__wfv__reached-glossary-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF reached-glossary-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 1, "name": "s82b-control-minimal-end", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:14+00:00", "staged": "00002__wfv__s82b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82b", "pass": 2, "name": "s82b-control-minimal-end", "sha256": "5ddc836d0a28a1d8fe097bb0463cdda84a03c18d4ee04e960e37a6dc4fbcd515", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:23:42+00:00", "staged": "00002__wfv__s82b-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82b-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "s82c-control-minimal", "sha256": "c8f2e5acd1898557d70774560dad71d0073f5f0496f6cc9c7210448e6e6f1504", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00001__wfv__s82c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "s82c-control-minimal", "sha256": "c8f2e5acd1898557d70774560dad71d0073f5f0496f6cc9c7210448e6e6f1504", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00001__wfv__s82c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "unused-header1-link-refused-type", "sha256": "0a347eea94861f595cf2ae03ebdd27da6671c06c97b575c2c05138b16aea3276", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00005__wfv__unused-header1-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header1-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "unused-header1-link-refused-type", "sha256": "0a347eea94861f595cf2ae03ebdd27da6671c06c97b575c2c05138b16aea3276", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00005__wfv__unused-header1-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header1-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "unused-header1-link-calibration", "sha256": "561c4e4b2297aaade1efc6284e0b1b27928e1e382de2fac2ff5472bc2dc76b80", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00004__wfv__unused-header1-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header1-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "unused-header1-link-calibration", "sha256": "561c4e4b2297aaade1efc6284e0b1b27928e1e382de2fac2ff5472bc2dc76b80", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00004__wfv__unused-header1-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-header1-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "unused-footnotes-link-refused-type", "sha256": "0aca6a4133892f1745ff2a36337c3c1a766a49d3166a658908c0f048b5bb5d18", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00003__wfv__unused-footnotes-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-footnotes-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "unused-footnotes-link-refused-type", "sha256": "0aca6a4133892f1745ff2a36337c3c1a766a49d3166a658908c0f048b5bb5d18", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00003__wfv__unused-footnotes-link-refused-type.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-footnotes-link-refused-type_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "unused-footnotes-link-calibration", "sha256": "828f7845e2d92958ce06096f8a2071fee8013dc6540614744e682ef1c7013a4f", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00002__wfv__unused-footnotes-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-footnotes-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "unused-footnotes-link-calibration", "sha256": "828f7845e2d92958ce06096f8a2071fee8013dc6540614744e682ef1c7013a4f", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00002__wfv__unused-footnotes-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF unused-footnotes-link-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "used-footnotes-link-refused-type", "sha256": "18c64afcf355ec94c59b2ad0af4f20ea115e4f528ca66613eef42d3f650c49bb", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00007__wfv__used-footnotes-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:25:19.514 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00007__wfv__used-footnotes-link-refus...)'", "2026-10-28 08:25:19.665 \"Word found unreadable content in 00007__wfv__used-footnotes-link-refused-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s82c", "pass": 2, "name": "used-footnotes-link-refused-type", "sha256": "18c64afcf355ec94c59b2ad0af4f20ea115e4f528ca66613eef42d3f650c49bb", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00007__wfv__used-footnotes-link-refused-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 08:25:44.700 \"Word found unreadable content in 00007__wfv__used-footnotes-link-refused-type.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__used-footnotes-link-refused-type.docx; refusing to guess"}
{"run": "s82c", "pass": 1, "name": "used-footnotes-link-calibration", "sha256": "78c5a2413d032e8b4112cc08fd95d934cbe446940a93161cb35fb4a7b975ea01", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00006__wfv__used-footnotes-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF used-footnotes-link-calibration_byword.pdf (16365 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "used-footnotes-link-calibration", "sha256": "78c5a2413d032e8b4112cc08fd95d934cbe446940a93161cb35fb4a7b975ea01", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00006__wfv__used-footnotes-link-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF used-footnotes-link-calibration_byword.pdf (16365 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 1, "name": "s82c-control-minimal-end", "sha256": "c8f2e5acd1898557d70774560dad71d0073f5f0496f6cc9c7210448e6e6f1504", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:19+00:00", "staged": "00000__wfv__s82c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s82c", "pass": 2, "name": "s82c-control-minimal-end", "sha256": "c8f2e5acd1898557d70774560dad71d0073f5f0496f6cc9c7210448e6e6f1504", "validatorRevision": "1661e12f488567cd6a8abef2403329eae336bc54", "observedAt": "2026-10-28T12:25:44+00:00", "staged": "00000__wfv__s82c-control-minimal-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s82c-control-minimal-end_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 82 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s82builder.mts`:

```ts
// Session 82 (2026-10-28): which parts Word judges a hyperlink's relationship in (#1106).
// `word-hyperlink-relationship` walks `ctx.storyParts()`, the parts named like a story wherever stored, not the parts Word
// reads. Session 28 (s28a) showed Word refuse a `w:hyperlink` whose relationship has the Type `…/relationships/HYPERLINK`
// in word/document.xml and open the exact Transitional Type clean. Each row here puts that shape (refused Type, TargetMode
// External, a URL target) in one placement, beside its calibration with the exact Type:
// s82a: the main document stored as word/document.xml (s28a repeated), the main document stored as word/main.xml, a used
// header stored as word/header1.xml, and a used header stored as word/hdr.xml.
// s82b: an unrelated word/header9.xml typed header by its Override (no relationship names it), a glossary stored as
// word/glossary/document.xml that no relationship reaches, and the same glossary reached by the main document's
// glossaryDocument relationship.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper and the glossary are
// s81builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825), and its src (#985).
// Run from a worktree root: CHUNK=s82a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const CT = "[Content_Types].xml";
const SIDECAR = "word/_rels/document.xml.rels";
const P = MINIMAL_PARTS as Record<string, string>;
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const relsPart = (body: string) => `${XML_DECL}<Relationships xmlns="${PR}">${body}</Relationships>`;

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const MAIN = P["word/document.xml"]!;
const overrides = (ct: string, ...pairs: [string, string][]) =>
    pairs.reduce(
        (types, [part, type]) => replaceOnce(types, "</Types>", `<Override PartName="/${part}" ContentType="${type}"/></Types>`),
        ct,
    );
const withR = (doc: string) => replaceOnce(doc, `<w:document xmlns:w="${W}"`, `<w:document xmlns:w="${W}" xmlns:r="${R}"`);

/** Session 28's refused Type, and the exact Transitional Type its calibration uses. */
const REFUSED = "HYPERLINK";
const EXACT = "hyperlink";
/** The hyperlink relationship rIdL of Type segment `segment`, External, to a URL. */
const linkRelationship = (segment: string) =>
    `<Relationship Id="rIdL" Type="${R}/${segment}" Target="https://example.com/" TargetMode="External"/>`;
const LINK_PARAGRAPH = '<w:p><w:hyperlink r:id="rIdL"><w:r><w:t>Link</w:t></w:r></w:hyperlink></w:p>';

/** The main document stored at `mainPart` holding the hyperlink, its sidecar relating the styles part and rIdL. */
const mainWithLink = (mainPart: string, segment: string): Record<string, string> => {
    const parts: Record<string, string> = { ...P };
    const doc = replaceOnce(withR(MAIN), "<w:sectPr>", `${LINK_PARAGRAPH}<w:sectPr>`);
    const sidecar = appendRels(P[SIDECAR]!, linkRelationship(segment));
    if (mainPart === "word/document.xml") return { ...parts, "word/document.xml": doc, [SIDECAR]: sidecar };
    delete parts["word/document.xml"];
    delete parts[SIDECAR];
    const name = path.posix.basename(mainPart);
    return {
        ...parts,
        [mainPart]: doc,
        [`word/_rels/${name}.rels`]: sidecar,
        "_rels/.rels": replaceOnce(P["_rels/.rels"]!, 'Target="word/document.xml"', `Target="${mainPart}"`),
        [CT]: replaceOnce(P[CT]!, 'PartName="/word/document.xml"', `PartName="/${mainPart}"`),
    };
};

const HEADER_WITH_LINK = `${XML_DECL}<w:hdr xmlns:w="${W}" xmlns:r="${R}">${LINK_PARAGRAPH}</w:hdr>`;
/** A header stored at word/`headerName` holding the hyperlink, its sidecar relating rIdL, referenced by the section. */
const usedHeaderWithLink = (headerName: string, segment: string): Record<string, string> => ({
    ...P,
    "word/document.xml": replaceOnce(withR(MAIN), "<w:sectPr>", '<w:sectPr><w:headerReference w:type="default" r:id="rIdH"/>'),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", headerName)),
    [`word/${headerName}`]: HEADER_WITH_LINK,
    [`word/_rels/${headerName}.rels`]: relsPart(linkRelationship(segment)),
    [CT]: overrides(P[CT]!, [`word/${headerName}`, `${WML}.header+xml`]),
});
/** The same header stored as word/header9.xml and typed header, which no relationship names. */
const unrelatedHeaderWithLink = (segment: string): Record<string, string> => ({
    ...P,
    "word/header9.xml": HEADER_WITH_LINK,
    "word/_rels/header9.xml.rels": relsPart(linkRelationship(segment)),
    [CT]: overrides(P[CT]!, ["word/header9.xml", `${WML}.header+xml`]),
});

const glossaryWithLink =
    `${XML_DECL}<w:glossaryDocument xmlns:w="${W}" xmlns:r="${R}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
    `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E11}"/></w:docPartPr>` +
    `<w:docPartBody>${LINK_PARAGRAPH}</w:docPartBody></w:docPart></w:docParts></w:glossaryDocument>`;
/** A glossary stored as word/glossary/document.xml holding the hyperlink; the main document relates it when `reached`. */
const glossaryLink = (reached: boolean, segment: string): Record<string, string> => ({
    ...P,
    "word/glossary/document.xml": glossaryWithLink,
    "word/glossary/_rels/document.xml.rels": relsPart(linkRelationship(segment)),
    ...(reached ? { [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")) } : {}),
    [CT]: overrides(P[CT]!, ["word/glossary/document.xml", `${WML}.document.glossary+xml`]),
});

/** A header stored as word/header1.xml holding the hyperlink, which the main document relates but no section references. */
const unusedHeaderWithLink = (segment: string): Record<string, string> => ({
    ...P,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
    "word/header1.xml": HEADER_WITH_LINK,
    "word/_rels/header1.xml.rels": relsPart(linkRelationship(segment)),
    [CT]: overrides(P[CT]!, ["word/header1.xml", `${WML}.header+xml`]),
});
const FOOTNOTES_WITH_LINK = `${XML_DECL}<w:footnotes xmlns:w="${W}" xmlns:r="${R}"><w:footnote w:id="1">${LINK_PARAGRAPH}</w:footnote></w:footnotes>`;
/** word/footnotes.xml whose footnote 1 holds the hyperlink, related by the main document, which references it when `used`. */
const footnotesWithLink = (used: boolean, segment: string): Record<string, string> => ({
    ...P,
    ...(used
        ? {
              "word/document.xml": replaceOnce(
                  MAIN,
                  "<w:r><w:t>Hello</w:t></w:r>",
                  '<w:r><w:t>Hello</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r>',
              ),
          }
        : {}),
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdN", "footnotes", "footnotes.xml")),
    "word/footnotes.xml": FOOTNOTES_WITH_LINK,
    "word/_rels/footnotes.xml.rels": relsPart(linkRelationship(segment)),
    [CT]: overrides(P[CT]!, ["word/footnotes.xml", `${WML}.footnotes+xml`]),
});

type Row = [string, string, () => Promise<Uint8Array>];
const control = () => buildDocx({ ...P });
const withControls = (chunk: string, rows: Row[]): Row[] => [
    [`${chunk}-control-minimal`, "control", control],
    ...rows,
    [`${chunk}-control-minimal-end`, "control", control],
];

const chunks: Record<string, Row[]> = {
    s82a: withControls("s82a", [
        [
            "main-link-refused-type",
            "#1106: s28a repeated, a hyperlink in word/document.xml whose relationship has the Type …/HYPERLINK",
            () => buildDocx(mainWithLink("word/document.xml", REFUSED)),
        ],
        [
            "main-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(mainWithLink("word/document.xml", EXACT)),
        ],
        [
            "renamed-main-link-refused-type",
            "#1106: the same hyperlink in a main document stored as word/main.xml",
            () => buildDocx(mainWithLink("word/main.xml", REFUSED)),
        ],
        [
            "renamed-main-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(mainWithLink("word/main.xml", EXACT)),
        ],
        [
            "header1-link-refused-type",
            "#1106: the same hyperlink in a used header stored as word/header1.xml",
            () => buildDocx(usedHeaderWithLink("header1.xml", REFUSED)),
        ],
        [
            "header1-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(usedHeaderWithLink("header1.xml", EXACT)),
        ],
        [
            "renamed-header-link-refused-type",
            "#1106: the same hyperlink in a used header stored as word/hdr.xml",
            () => buildDocx(usedHeaderWithLink("hdr.xml", REFUSED)),
        ],
        [
            "renamed-header-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(usedHeaderWithLink("hdr.xml", EXACT)),
        ],
    ]),
    s82b: withControls("s82b", [
        [
            "unrelated-header9-link-refused-type",
            "#1106: the same hyperlink in word/header9.xml, typed header, which no relationship names",
            () => buildDocx(unrelatedHeaderWithLink(REFUSED)),
        ],
        [
            "unrelated-header9-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(unrelatedHeaderWithLink(EXACT)),
        ],
        [
            "unreached-glossary-link-refused-type",
            "#1106: the same hyperlink in word/glossary/document.xml, which no relationship reaches",
            () => buildDocx(glossaryLink(false, REFUSED)),
        ],
        [
            "unreached-glossary-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(glossaryLink(false, EXACT)),
        ],
        [
            "reached-glossary-link-refused-type",
            "#1106: the same hyperlink in a glossary the main document relates",
            () => buildDocx(glossaryLink(true, REFUSED)),
        ],
        [
            "reached-glossary-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(glossaryLink(true, EXACT)),
        ],
    ]),
    // s82c: the stories the read model leaves out because their root does not use them, beside a used notes part.
    s82c: withControls("s82c", [
        [
            "unused-header1-link-refused-type",
            "#1106: the same hyperlink in word/header1.xml, which the main document relates but no section references",
            () => buildDocx(unusedHeaderWithLink(REFUSED)),
        ],
        [
            "unused-header1-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(unusedHeaderWithLink(EXACT)),
        ],
        [
            "unused-footnotes-link-refused-type",
            "#1106: the same hyperlink in footnote 1 of word/footnotes.xml, which the main document relates but does not reference",
            () => buildDocx(footnotesWithLink(false, REFUSED)),
        ],
        [
            "unused-footnotes-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(footnotesWithLink(false, EXACT)),
        ],
        [
            "used-footnotes-link-refused-type",
            "#1106: the same, the body referencing footnote 1",
            () => buildDocx(footnotesWithLink(true, REFUSED)),
        ],
        [
            "used-footnotes-link-calibration",
            "calibration: the same with the exact hyperlink Type",
            () => buildDocx(footnotesWithLink(true, EXACT)),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen for the staging and log-check
// scripts to pick up (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid} ${row.strict.errors.join(",")}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-82 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s82a", "s82b", "s82c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s82/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-82 parts of docs/plans/evidence/word-probes-2026-10-24.md into s82/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s82a", "s82b", "s82c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s82/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e.split('@')[0]}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            record = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                      "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                      "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                      "pdf": row["pdf"], "evidence": row["evidence"]}
            error = manifest(r, s["file"]).get("error")
            if error:
                record["error"] = error
            raw.append(json.dumps(record, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

# The rows Word refused: the refused Type in a part Word reads.
REFUSED = {"main-link-refused-type.docx", "renamed-main-link-refused-type.docx", "header1-link-refused-type.docx",
           "renamed-header-link-refused-type.docx", "reached-glossary-link-refused-type.docx",
           "used-footnotes-link-refused-type.docx"}
# The rows word-valid at the probed revision gets wrong: two misses, four rejections of a part Word does not read.
MISSED = {"renamed-main-link-refused-type.docx", "renamed-header-link-refused-type.docx"}
OVERREACH = {"unrelated-header9-link-refused-type.docx", "unreached-glossary-link-refused-type.docx",
             "unused-header1-link-refused-type.docx", "unused-footnotes-link-refused-type.docx"}
# The narrative's claims about outcomes, checked against results.json: every row's four readings agree, the refused
# rows were refused and every other row opened clean, and word-valid at the probed revision gets exactly MISSED and
# OVERREACH wrong.
for (label, file), r in results.items():
    assert r["agreed"], (label, file, r)
    assert set(r["readings"]) == ({"repair-warning"} if file in REFUSED else {"clean-open"}), (label, file, r)
    assert r["wordValid"] is ((file not in REFUSED or file in MISSED) and file not in OVERREACH), (label, file, r)
    assert r["validatorMatchesWord"] is (file not in MISSED | OVERREACH), (label, file, r)
assert agreed == len(rows) == 26, (agreed, len(rows))
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == files, (run, opened)
# The text Word rendered in each clean row, both runs: the hyperlink's "Link" after "Hello" in a main document, before
# it in a header, and as the used note's text after the body's "Hello1"; "Hello" alone where Word did not read the part
# holding it. A refused row left no PDF.
RENDERED = {"main-link-calibration.docx": "Hello Link", "renamed-main-link-calibration.docx": "Hello Link",
            "header1-link-calibration.docx": "Link Hello", "renamed-header-link-calibration.docx": "Link Hello",
            "used-footnotes-link-calibration.docx": "Hello1 Link"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
            file = json.loads(line)["original_filename"]
            text = rendered(run, file)
            assert text == (None if file in REFUSED else RENDERED.get(file, "Hello")), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 82: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Which parts Word judges a hyperlink's relationship in "
    "([#1106](https://github.com/jandira-tech/docx-validate/issues/1106)). `word-hyperlink-relationship` judged the "
    "parts named like a story wherever stored, not the parts Word reads. Each row holds session 28's refused shape in one "
    "placement: a `w:hyperlink` holding `Link` whose relationship has the Type `…/relationships/HYPERLINK`, TargetMode "
    "External, a URL target (s28a refused it in `word/document.xml`); its calibration uses the exact Transitional Type. "
    "Chunk s82a places it in `word/document.xml` (s28a repeated), in a main document stored as `word/main.xml`, in a used "
    "header stored as `word/header1.xml` and in a used header stored as `word/hdr.xml`. Chunk s82b places it in "
    "`word/header9.xml`, typed header by its Override, which no relationship names; in a glossary stored as "
    "`word/glossary/document.xml` that no relationship reaches; and in the same glossary reached by the main document's "
    "`glossaryDocument` relationship. Chunk s82c places it in `word/header1.xml`, which the main document relates but no "
    "section references, and in footnote 1 of `word/footnotes.xml`, which the main document relates and does not "
    "reference, then does. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's "
    "rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is "
    f"the manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows "
    "agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of "
    f"the specimen. The builder recorded the validator revision in every row (`{rev}`).",
    "",
    "Every calibration and control opened clean. Word rendered `Link` where it read the part holding the hyperlink: "
    "after `Hello` in both main documents, before it in both used headers, and after the body's `Hello1` as the used "
    "note's text; every other clean row's PDF holds `Hello` alone (`pdftotext`, both runs). No refused row left a PDF.",
    "",
    "- **Word judges the hyperlink in the parts it reads, whatever their names.** It offered recovery for the refused "
    "Type in `word/document.xml`, in the main document stored as `word/main.xml`, in both used headers, in the reached "
    "glossary and in the used footnotes part.",
    "- **It does not judge a part it does not read.** It opened the refused Type clean in the unrelated "
    "`word/header9.xml`, in the unreached glossary, in the header no section references and in the footnotes part "
    "nothing references, as the read model says it reads none of them (session 17 for the glossary, #726 and #800 for "
    "the stories).",
    "",
    f"Word-valid at {at} judged by name, so it matches Word on {matches} of {len(rows)} rows: it passes the refused Type "
    "in the renamed main document and the renamed header, and rejects it in the four parts Word does not read. "
    "[#1106](https://github.com/jandira-tech/docx-validate/issues/1106) moves the rule onto the read model and pins "
    "every row in `tests/word-hyperlink-relationship.test.ts`.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 82</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 82 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s82builder.mts", ROOT / "s82builder.mts", "ts"), ("compare.py", ROOT / "s82/compare.py", "python"),
                         ("section.py", ROOT / "s82/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s82/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 83: 13:05Z–13:09Z on 2026-10-28, validator columns at 568d746a

Whether Word judges [#1113](https://github.com/jandira-tech/docx-validate/issues/1113)'s Word-blocking rules in the parts it reads, as session 82 found for the hyperlink relationship. Twenty check files, holding 26 Word rules, judge the parts named like a story wherever stored (`STORY_PART`), not the parts Word reads. Eleven of those rules, in eight of the files, have a Word-refused fixture whose finding is only in `word/document.xml` and a clean twin (session 41's pairs; the `-shape` pair for `word-textbox-deleted-text`, whose plain fixture holds its defect in a footer). Each pair gives three rows: `-main` is the broken fixture with its main document stored as `word/main.xml`, with `_rels/.rels`, the content-types Override and the part's own relationships following the name; `-main-calibration` is the clean twin renamed the same way; `-unrelated-header` is the clean twin plus `word/header83.xml`, typed header by its Override, which no relationship names, holding the broken fixture's body under a `w:hdr` root with its `w:sectPr` removed, and the broken main document's relationships as its own. Chunk s83a holds `word-row-without-cell`, `word-cell-ends-with-table` and `word-drawing-arc-radius`; s83b `word-drawing-extent-negative`, `word-empty-drawing` and `word-anchor-missing-attribute`; s83c `word-text-contains-paragraph`, `word-textbox-deleted-text` and `word-move-from-deleted-text`; s83d `word-sdt-id-empty` and `word-choice-requires-undeclared`. Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 37 of 37 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`568d746adf4aaa478735b82672c3bbd66c858355`). The strict column leaves out the `rels-unreferenced`, `paraid-missing-element`, `xsd-summary` and `xsd-error` findings and names every other strict error, so beside the probed rule it also names fixture findings such as `textid-missing-element` and `style-default-missing` (#1124).

Every calibration and control opened clean. Each unrelated header's PDF holds exactly its calibration's text in both runs (`pdftotext`; the `word-empty-drawing` and `word-choice-requires-undeclared` twins render no text), and each control's holds `Hello`. No refused row left a PDF.

- **Word judges the eleven shapes in a main document whatever its name.** It refused all eleven renamed main documents, as it did in `word/document.xml` (session 41): an open error for 7 (`word-row-without-cell`, `word-drawing-arc-radius`, `word-drawing-extent-negative`, `word-empty-drawing`, `word-anchor-missing-attribute`, `word-text-contains-paragraph`, `word-sdt-id-empty`) and an offer to recover unreadable content for 4 (`word-cell-ends-with-table`, `word-textbox-deleted-text`, `word-move-from-deleted-text`, `word-choice-requires-undeclared`).
- **It does not judge them in a part it does not read.** It opened every shape clean in the unrelated `word/header83.xml`, as the read model says it reads no part that no relationship names (#726).

Word-valid at 568d746a judged by name, so it matches Word on 16 of 37 rows: it passes ten of the renamed main documents and rejects all eleven unrelated headers. It rejects the renamed `word-choice-requires-undeclared` row only through `mce-malformed`, which judges every part: that rule also rejects the unrelated header Word opened clean. [#1113](https://github.com/jandira-tech/docx-validate/issues/1113) moves the rules onto the read model.

| Run    | Observed             | Specimen                                      | Shape                                                                                                                                                                                                 | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 568d746a                                                                                         | strict at 568d746a                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------ | -------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s83a` | 13:05:05Z, 13:05:42Z | `row-without-cell-main`                       | #1113 word-row-without-cell: broken/package.word-row-without-cell.docx with its main document stored as word/main.xml                                                                                 | `6898506a85f56ac0` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: fixture findings only                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `s83a` | 13:05:05Z, 13:05:42Z | `row-without-cell-main-calibration`           | calibration: working/package.word-row-without-cell-repaired.docx renamed the same way                                                                                                                 | `e29855811614e44f` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: fixture findings only                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `s83a` | 13:05:05Z, 13:05:42Z | `row-without-cell-unrelated-header`           | #1113 word-row-without-cell: working/package.word-row-without-cell-repaired.docx plus an unrelated word/header83.xml holding broken/package.word-row-without-cell.docx's body                         | `88918eb4f9770908` | clean-open     | clean-open     | clean-open                 | invalid: `word-row-without-cell@word/header83.xml`                                                             | invalid: `word-row-without-cell@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                                                                       |
| `s83a` | 13:05:05Z, 13:05:42Z | `cell-ends-with-table-main`                   | #1113 word-cell-ends-with-table: broken/package.word-cell-ends-with-table.docx with its main document stored as word/main.xml                                                                         | `78dd9459bb1a9999` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                                                          | invalid: fixture findings only                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `s83a` | 13:05:05Z, 13:05:42Z | `cell-ends-with-table-main-calibration`       | calibration: working/package.word-cell-ends-with-table-repaired.docx renamed the same way                                                                                                             | `9a5ed31160c7cf4a` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: fixture findings only                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `s83a` | 13:05:05Z, 13:05:42Z | `cell-ends-with-table-unrelated-header`       | #1113 word-cell-ends-with-table: working/package.word-cell-ends-with-table-repaired.docx plus an unrelated word/header83.xml holding broken/package.word-cell-ends-with-table.docx's body             | `79866adac23a0c41` | clean-open     | clean-open     | clean-open                 | invalid: `word-cell-ends-with-table@word/header83.xml`                                                         | invalid: `word-cell-ends-with-table@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                                                                   |
| `s83a` | 13:05:05Z, 13:05:42Z | `arc-radius-main`                             | #1113 word-drawing-arc-radius: broken/package.drawing-arc-radius.docx with its main document stored as word/main.xml                                                                                  | `9ae79c73217b4984` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83a` | 13:05:05Z, 13:05:42Z | `arc-radius-main-calibration`                 | calibration: working/package.drawing-arc-radius-integer.docx renamed the same way                                                                                                                     | `56caf5d371a45434` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83a` | 13:05:05Z, 13:05:42Z | `arc-radius-unrelated-header`                 | #1113 word-drawing-arc-radius: working/package.drawing-arc-radius-integer.docx plus an unrelated word/header83.xml holding broken/package.drawing-arc-radius.docx's body                              | `bf1c31d01064ecc1` | clean-open     | clean-open     | clean-open                 | invalid: `word-drawing-arc-radius@word/header83.xml`                                                           | invalid: `style-default-missing@word/styles.xml`, `word-drawing-arc-radius@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                            |
| `s83a` | 13:05:05Z, 13:05:42Z | `s83a-control-minimal`                        | control                                                                                                                                                                                               | `35ccde0e908ed032` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83b` | 13:06:30Z, 13:07:09Z | `extent-negative-main`                        | #1113 word-drawing-extent-negative: broken/package.word-drawing-extent-negative.docx with its main document stored as word/main.xml                                                                   | `d50ca2b9d3bf2bc4` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83b` | 13:06:30Z, 13:07:09Z | `extent-negative-main-calibration`            | calibration: working/package.word-drawing-extent-positive.docx renamed the same way                                                                                                                   | `19385147d608bb97` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83b` | 13:06:30Z, 13:07:09Z | `extent-negative-unrelated-header`            | #1113 word-drawing-extent-negative: working/package.word-drawing-extent-positive.docx plus an unrelated word/header83.xml holding broken/package.word-drawing-extent-negative.docx's body             | `8abb3984c8c5832d` | clean-open     | clean-open     | clean-open                 | invalid: `word-drawing-extent-negative@word/header83.xml`                                                      | invalid: `style-default-missing@word/styles.xml`, `word-drawing-extent-negative@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                       |
| `s83b` | 13:06:30Z, 13:07:09Z | `empty-drawing-main`                          | #1113 word-empty-drawing: broken/package.word-empty-drawing.docx with its main document stored as word/main.xml                                                                                       | `aa3d14e4acb6e648` | open-error     | open-error     | open-error                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83b` | 13:06:30Z, 13:07:09Z | `empty-drawing-main-calibration`              | calibration: working/package.word-empty-drawing-removed.docx renamed the same way                                                                                                                     | `7a753ec7b3b73c77` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83b` | 13:06:30Z, 13:07:09Z | `empty-drawing-unrelated-header`              | #1113 word-empty-drawing: working/package.word-empty-drawing-removed.docx plus an unrelated word/header83.xml holding broken/package.word-empty-drawing.docx's body                                   | `8a209e173789b41f` | clean-open     | clean-open     | clean-open                 | invalid: `word-empty-drawing@word/header83.xml`                                                                | invalid: `word-empty-drawing@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                                                                          |
| `s83b` | 13:06:30Z, 13:07:09Z | `anchor-open-main`                            | #1113 word-anchor-missing-attribute: broken/package.word-anchor-open.docx with its main document stored as word/main.xml                                                                              | `7c47ed53a8c75213` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83b` | 13:06:30Z, 13:07:09Z | `anchor-open-main-calibration`                | calibration: working/package.word-anchor-open-repaired.docx renamed the same way                                                                                                                      | `b2a392056dcc0fbf` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83b` | 13:06:30Z, 13:07:09Z | `anchor-open-unrelated-header`                | #1113 word-anchor-missing-attribute: working/package.word-anchor-open-repaired.docx plus an unrelated word/header83.xml holding broken/package.word-anchor-open.docx's body                           | `841dcc38c6666414` | clean-open     | clean-open     | clean-open                 | invalid: `word-anchor-missing-attribute@word/header83.xml`, `word-position-offset-and-align@word/header83.xml` | invalid: `style-default-missing@word/styles.xml`, `word-anchor-missing-attribute@word/header83.xml`, `word-position-offset-and-align@word/header83.xml`                                                                                                                                                                                                                                                                                                  |
| `s83b` | 13:06:30Z, 13:07:09Z | `s83b-control-minimal`                        | control                                                                                                                                                                                               | `b816c3963669bf1d` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83c` | 13:07:48Z, 13:08:23Z | `text-contains-paragraph-main`                | #1113 word-text-contains-paragraph: broken/package.word-text-contains-paragraph.docx with its main document stored as word/main.xml                                                                   | `95e3630dd34985bd` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83c` | 13:07:48Z, 13:08:23Z | `text-contains-paragraph-main-calibration`    | calibration: working/package.word-text-contains-paragraph-lifted.docx renamed the same way                                                                                                            | `357aabbb9ef96df7` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `style-default-missing@word/styles.xml`                                                                                                                                                                                                                                                                                                                                                                                                         |
| `s83c` | 13:07:48Z, 13:08:23Z | `text-contains-paragraph-unrelated-header`    | #1113 word-text-contains-paragraph: working/package.word-text-contains-paragraph-lifted.docx plus an unrelated word/header83.xml holding broken/package.word-text-contains-paragraph.docx's body      | `212be1c5fd0b93a3` | clean-open     | clean-open     | clean-open                 | invalid: `word-text-contains-paragraph@word/header83.xml`                                                      | invalid: `ws-missing-preserve@word/document.xml`, `style-default-missing@word/styles.xml`, `word-text-contains-paragraph@word/header83.xml`                                                                                                                                                                                                                                                                                                              |
| `s83c` | 13:07:48Z, 13:08:23Z | `textbox-deleted-text-main`                   | #1113 word-textbox-deleted-text: broken/package.word-textbox-deleted-text-shape.docx with its main document stored as word/main.xml                                                                   | `3046841f76c1612d` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                                                          | invalid: `comment-thread-count-mismatch@word/main.xml`                                                                                                                                                                                                                                                                                                                                                                                                   |
| `s83c` | 13:07:48Z, 13:08:23Z | `textbox-deleted-text-main-calibration`       | calibration: working/package.word-textbox-deleted-text-shape-repaired.docx renamed the same way                                                                                                       | `f39d2f0e8f8c2b73` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `comment-thread-count-mismatch@word/main.xml`                                                                                                                                                                                                                                                                                                                                                                                                   |
| `s83c` | 13:07:48Z, 13:08:23Z | `textbox-deleted-text-unrelated-header`       | #1113 word-textbox-deleted-text: working/package.word-textbox-deleted-text-shape-repaired.docx plus an unrelated word/header83.xml holding broken/package.word-textbox-deleted-text-shape.docx's body | `5e20e1795aa52ddd` | clean-open     | clean-open     | clean-open                 | invalid: `word-textbox-deleted-text@word/header83.xml`                                                         | invalid: `comment-thread-count-mismatch@word/document.xml`, `word-textbox-deleted-text@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                |
| `s83c` | 13:07:48Z, 13:08:23Z | `move-from-deleted-text-main`                 | #1113 word-move-from-deleted-text: broken/package.word-move-from-deleted-text.docx with its main document stored as word/main.xml                                                                     | `c66eb457385e0f41` | repair-warning | repair-warning | unreadable-content-warning | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83c` | 13:07:48Z, 13:08:23Z | `move-from-deleted-text-main-calibration`     | calibration: working/package.word-move-from-text.docx renamed the same way                                                                                                                            | `27708437f8db8a5c` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83c` | 13:07:48Z, 13:08:23Z | `move-from-deleted-text-unrelated-header`     | #1113 word-move-from-deleted-text: working/package.word-move-from-text.docx plus an unrelated word/header83.xml holding broken/package.word-move-from-deleted-text.docx's body                        | `dea5c6100fbdd61b` | clean-open     | clean-open     | clean-open                 | invalid: `word-move-from-deleted-text@word/header83.xml`                                                       | invalid: `word-move-from-deleted-text@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                                                                 |
| `s83c` | 13:07:48Z, 13:08:23Z | `s83c-control-minimal`                        | control                                                                                                                                                                                               | `c23724cc657168b0` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `s83d` | 13:08:54Z, 13:09:24Z | `sdt-id-empty-main`                           | #1113 word-sdt-id-empty: broken/package.word-sdt-id-empty.docx with its main document stored as word/main.xml                                                                                         | `00c1ae4b3f9789cd` | open-error     | open-error     | open-error                 | valid                                                                                                          | invalid: `textid-missing-element@word/footer1.xml`, `textid-missing-element@word/footer2.xml`, `textid-missing-element@word/footnotes.xml`, `textid-missing-element@word/header1.xml`, `textid-missing-element@word/header2.xml`, `style-reference-undefined@word/footnotes.xml`, `style-default-missing@word/styles.xml`                                                                                                                                |
| `s83d` | 13:08:54Z, 13:09:24Z | `sdt-id-empty-main-calibration`               | calibration: working/package.word-sdt-id-empty-repaired.docx renamed the same way                                                                                                                     | `0b87300a94b9d569` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: `textid-missing-element@word/footer1.xml`, `textid-missing-element@word/footer2.xml`, `textid-missing-element@word/footnotes.xml`, `textid-missing-element@word/header1.xml`, `textid-missing-element@word/header2.xml`, `style-reference-undefined@word/footnotes.xml`, `style-default-missing@word/styles.xml`                                                                                                                                |
| `s83d` | 13:08:54Z, 13:09:24Z | `sdt-id-empty-unrelated-header`               | #1113 word-sdt-id-empty: working/package.word-sdt-id-empty-repaired.docx plus an unrelated word/header83.xml holding broken/package.word-sdt-id-empty.docx's body                                     | `e2bbd4661852c77d` | clean-open     | clean-open     | clean-open                 | invalid: `word-sdt-id-empty@word/header83.xml`                                                                 | invalid: `textid-missing-element@word/document.xml`, `textid-missing-element@word/footer1.xml`, `textid-missing-element@word/footer2.xml`, `textid-missing-element@word/footnotes.xml`, `textid-missing-element@word/header1.xml`, `textid-missing-element@word/header2.xml`, `textid-missing-element@word/header83.xml`, `style-reference-undefined@word/footnotes.xml`, `style-default-missing@word/styles.xml`, `word-sdt-id-empty@word/header83.xml` |
| `s83d` | 13:08:54Z, 13:09:24Z | `choice-requires-undeclared-main`             | #1113 word-choice-requires-undeclared: broken/package.word-choice-requires-undeclared.docx with its main document stored as word/main.xml                                                             | `04c7580a39bb3768` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-malformed@word/main.xml`                                                                         | invalid: `mce-malformed@word/main.xml`                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `s83d` | 13:08:54Z, 13:09:24Z | `choice-requires-undeclared-main-calibration` | calibration: working/package.word-choice-requires-declared.docx renamed the same way                                                                                                                  | `3b8a895d745a7516` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | invalid: fixture findings only                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `s83d` | 13:08:54Z, 13:09:24Z | `choice-requires-undeclared-unrelated-header` | #1113 word-choice-requires-undeclared: working/package.word-choice-requires-declared.docx plus an unrelated word/header83.xml holding broken/package.word-choice-requires-undeclared.docx's body      | `8aeee434603a730f` | clean-open     | clean-open     | clean-open                 | invalid: `mce-malformed@word/header83.xml`, `word-choice-requires-undeclared@word/header83.xml`                | invalid: `mce-malformed@word/header83.xml`, `word-choice-requires-undeclared@word/header83.xml`                                                                                                                                                                                                                                                                                                                                                          |
| `s83d` | 13:08:54Z, 13:09:24Z | `s83d-control-minimal`                        | control                                                                                                                                                                                               | `a7fde1a84a917de2` | clean-open     | clean-open     | clean-open                 | valid                                                                                                          | valid                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

<details><summary>Raw records, session 83</summary>

```jsonl
{"run": "s83a", "pass": 1, "name": "row-without-cell-main", "sha256": "6898506a85f56ac02408ba9bc6d3833cbc737e5031067d264f0368f9d9cde1e5", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00007__wfv__row-without-cell-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:04:33.568 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00007__wfv__row-without-cell-main.docx)\""], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__row-without-cell-main.docx; refusing to guess"}
{"run": "s83a", "pass": 2, "name": "row-without-cell-main", "sha256": "6898506a85f56ac02408ba9bc6d3833cbc737e5031067d264f0368f9d9cde1e5", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00007__wfv__row-without-cell-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:05:28.491 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … y converter.\\n(00007__wfv__row-without-cell-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__row-without-cell-main.docx; refusing to guess"}
{"run": "s83a", "pass": 1, "name": "row-without-cell-main-calibration", "sha256": "e29855811614e44f698eb1287adcd5b44d534dd3a80d1dba68d0751f0f0dd4c6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00006__wfv__row-without-cell-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF row-without-cell-main-calibration_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "row-without-cell-main-calibration", "sha256": "e29855811614e44f698eb1287adcd5b44d534dd3a80d1dba68d0751f0f0dd4c6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00006__wfv__row-without-cell-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF row-without-cell-main-calibration_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "row-without-cell-unrelated-header", "sha256": "88918eb4f9770908ab8277e607fce4f68af213d367f251fb98077ad090caab14", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00008__wfv__row-without-cell-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF row-without-cell-unrelated-header_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "row-without-cell-unrelated-header", "sha256": "88918eb4f9770908ab8277e607fce4f68af213d367f251fb98077ad090caab14", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00008__wfv__row-without-cell-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF row-without-cell-unrelated-header_byword.pdf (31738 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "cell-ends-with-table-main", "sha256": "78dd9459bb1a9999f5783bb5ac147e63b2add4837652128c42cae4019b619484", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00004__wfv__cell-ends-with-table-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:04:19.527 \"Word found unreadable content in 00004__wfv__cell-ends-with-table-main.docx. Do you want to recover … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83a", "pass": 2, "name": "cell-ends-with-table-main", "sha256": "78dd9459bb1a9999f5783bb5ac147e63b2add4837652128c42cae4019b619484", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00004__wfv__cell-ends-with-table-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:05:24.056 'Word found unreadable content in 00004__wfv__cell-ends-with-table-main.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:05:24.547 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__cell-ends-with-table-main...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83a", "pass": 1, "name": "cell-ends-with-table-main-calibration", "sha256": "9a5ed31160c7cf4a1c8085d28f94c9d32fc67f9ae374ba64ebec31fbb1424f70", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00003__wfv__cell-ends-with-table-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF cell-ends-with-table-main-calibration_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "cell-ends-with-table-main-calibration", "sha256": "9a5ed31160c7cf4a1c8085d28f94c9d32fc67f9ae374ba64ebec31fbb1424f70", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00003__wfv__cell-ends-with-table-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF cell-ends-with-table-main-calibration_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "cell-ends-with-table-unrelated-header", "sha256": "79866adac23a0c41a52b19bfdef7edea9fa104a4746dee6dcabaff7a9280a59d", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00005__wfv__cell-ends-with-table-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF cell-ends-with-table-unrelated-header_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "cell-ends-with-table-unrelated-header", "sha256": "79866adac23a0c41a52b19bfdef7edea9fa104a4746dee6dcabaff7a9280a59d", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00005__wfv__cell-ends-with-table-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF cell-ends-with-table-unrelated-header_byword.pdf (220866 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "arc-radius-main", "sha256": "9ae79c73217b4984d15f8ee9ca1be564de95d01a90f8c7e2bbebc7b72bb1c5a6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00001__wfv__arc-radius-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:04:05.293 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00001__wfv__arc-radius-main.docx)\""], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__arc-radius-main.docx; refusing to guess"}
{"run": "s83a", "pass": 2, "name": "arc-radius-main", "sha256": "9ae79c73217b4984d15f8ee9ca1be564de95d01a90f8c7e2bbebc7b72bb1c5a6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00001__wfv__arc-radius-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:05:19.705 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ecovery converter.\\n(00001__wfv__arc-radius-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__arc-radius-main.docx; refusing to guess"}
{"run": "s83a", "pass": 1, "name": "arc-radius-main-calibration", "sha256": "56caf5d371a45434f1bb4a299ac2fbffc2da32ba18f4e2e58b89f6d31e3865a0", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00000__wfv__arc-radius-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF arc-radius-main-calibration_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "arc-radius-main-calibration", "sha256": "56caf5d371a45434f1bb4a299ac2fbffc2da32ba18f4e2e58b89f6d31e3865a0", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00000__wfv__arc-radius-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF arc-radius-main-calibration_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "arc-radius-unrelated-header", "sha256": "bf1c31d01064ecc18aa9b8deb27fbb4dcaece81a55165ad46ed3ed1b8d24f576", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00002__wfv__arc-radius-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF arc-radius-unrelated-header_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "arc-radius-unrelated-header", "sha256": "bf1c31d01064ecc18aa9b8deb27fbb4dcaece81a55165ad46ed3ed1b8d24f576", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00002__wfv__arc-radius-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF arc-radius-unrelated-header_byword.pdf (100921 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 1, "name": "s83a-control-minimal", "sha256": "35ccde0e908ed032a538ac7adf2e21662c25765eaba53a10425b034f8eb5984b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:05+00:00", "staged": "00009__wfv__s83a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83a", "pass": 2, "name": "s83a-control-minimal", "sha256": "35ccde0e908ed032a538ac7adf2e21662c25765eaba53a10425b034f8eb5984b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:05:42+00:00", "staged": "00009__wfv__s83a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "extent-negative-main", "sha256": "d50ca2b9d3bf2bc43df277b11afd7004d487d21a35600c19a3afae27691ba645", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00007__wfv__extent-negative-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:11.908 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ry converter.\\n(00007__wfv__extent-negative-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__extent-negative-main.docx; refusing to guess"}
{"run": "s83b", "pass": 2, "name": "extent-negative-main", "sha256": "d50ca2b9d3bf2bc43df277b11afd7004d487d21a35600c19a3afae27691ba645", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00007__wfv__extent-negative-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:51.689 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … ry converter.\\n(00007__wfv__extent-negative-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00007__wfv__extent-negative-main.docx; refusing to guess"}
{"run": "s83b", "pass": 1, "name": "extent-negative-main-calibration", "sha256": "19385147d608bb978994e8a32bdced09a96b56bcfa82ac6aa9e6b46757a5f158", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00006__wfv__extent-negative-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF extent-negative-main-calibration_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "extent-negative-main-calibration", "sha256": "19385147d608bb978994e8a32bdced09a96b56bcfa82ac6aa9e6b46757a5f158", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00006__wfv__extent-negative-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF extent-negative-main-calibration_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "extent-negative-unrelated-header", "sha256": "8abb3984c8c5832d73c8db8a69ad6197572c2fd7728d9cdb4186dc28cfc6ab32", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00008__wfv__extent-negative-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF extent-negative-unrelated-header_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "extent-negative-unrelated-header", "sha256": "8abb3984c8c5832d73c8db8a69ad6197572c2fd7728d9cdb4186dc28cfc6ab32", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00008__wfv__extent-negative-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF extent-negative-unrelated-header_byword.pdf (85498 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "empty-drawing-main", "sha256": "aa3d14e4acb6e6486d5bebafa480bb44afe99f3664c98a6163feb8e8bae8ab0b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00004__wfv__empty-drawing-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:07.732 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … very converter.\\n(00004__wfv__empty-drawing-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__empty-drawing-main.docx; refusing to guess"}
{"run": "s83b", "pass": 2, "name": "empty-drawing-main", "sha256": "aa3d14e4acb6e6486d5bebafa480bb44afe99f3664c98a6163feb8e8bae8ab0b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00004__wfv__empty-drawing-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:47.490 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … very converter.\\n(00004__wfv__empty-drawing-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__empty-drawing-main.docx; refusing to guess"}
{"run": "s83b", "pass": 1, "name": "empty-drawing-main-calibration", "sha256": "7a753ec7b3b73c771af501a1b052808fe44ab360f462742684e9eae334308fd4", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00003__wfv__empty-drawing-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF empty-drawing-main-calibration_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "empty-drawing-main-calibration", "sha256": "7a753ec7b3b73c771af501a1b052808fe44ab360f462742684e9eae334308fd4", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00003__wfv__empty-drawing-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF empty-drawing-main-calibration_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "empty-drawing-unrelated-header", "sha256": "8a209e173789b41f07be7024c993a6a79e6af6eee1043fc04367b9bce0d2712e", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00005__wfv__empty-drawing-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF empty-drawing-unrelated-header_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "empty-drawing-unrelated-header", "sha256": "8a209e173789b41f07be7024c993a6a79e6af6eee1043fc04367b9bce0d2712e", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00005__wfv__empty-drawing-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF empty-drawing-unrelated-header_byword.pdf (4923 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "anchor-open-main", "sha256": "7c47ed53a8c752137871eec0491a514e3a13107f55b4d82816f07a1715b40c71", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00001__wfv__anchor-open-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:03.272 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … covery converter.\\n(00001__wfv__anchor-open-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__anchor-open-main.docx; refusing to guess"}
{"run": "s83b", "pass": 2, "name": "anchor-open-main", "sha256": "7c47ed53a8c752137871eec0491a514e3a13107f55b4d82816f07a1715b40c71", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00001__wfv__anchor-open-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:06:43.022 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … covery converter.\\n(00001__wfv__anchor-open-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00001__wfv__anchor-open-main.docx; refusing to guess"}
{"run": "s83b", "pass": 1, "name": "anchor-open-main-calibration", "sha256": "b2a392056dcc0fbf2416ab49b96c6502457ed665f94090f3be9cebb1bd9f5365", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00000__wfv__anchor-open-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF anchor-open-main-calibration_byword.pdf (167146 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "anchor-open-main-calibration", "sha256": "b2a392056dcc0fbf2416ab49b96c6502457ed665f94090f3be9cebb1bd9f5365", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00000__wfv__anchor-open-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF anchor-open-main-calibration_byword.pdf (167146 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "anchor-open-unrelated-header", "sha256": "841dcc38c6666414fe136f7a9b3e2f315b583e3412803a918a6b56a3dd5c265b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00002__wfv__anchor-open-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF anchor-open-unrelated-header_byword.pdf (167146 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "anchor-open-unrelated-header", "sha256": "841dcc38c6666414fe136f7a9b3e2f315b583e3412803a918a6b56a3dd5c265b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00002__wfv__anchor-open-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF anchor-open-unrelated-header_byword.pdf (167146 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 1, "name": "s83b-control-minimal", "sha256": "b816c3963669bf1d8be772d2a137abee64601e8f5c3b8392f6248329591dc745", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:06:30+00:00", "staged": "00009__wfv__s83b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83b", "pass": 2, "name": "s83b-control-minimal", "sha256": "b816c3963669bf1d8be772d2a137abee64601e8f5c3b8392f6248329591dc745", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:09+00:00", "staged": "00009__wfv__s83b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "text-contains-paragraph-main", "sha256": "95e3630dd34985bd98dd945dd4d1c048736ea444a6d9df075b7a7f5da0f9442e", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00005__wfv__text-contains-paragraph-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:07:34.957 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00005__wfv__text-contains-paragraph-m...)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__text-contains-paragraph-main.docx; refusing to guess"}
{"run": "s83c", "pass": 2, "name": "text-contains-paragraph-main", "sha256": "95e3630dd34985bd98dd945dd4d1c048736ea444a6d9df075b7a7f5da0f9442e", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00005__wfv__text-contains-paragraph-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:08:07.234 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00005__wfv__text-contains-paragraph-m...)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__text-contains-paragraph-main.docx; refusing to guess"}
{"run": "s83c", "pass": 1, "name": "text-contains-paragraph-main-calibration", "sha256": "357aabbb9ef96df7664eeb3699f3b1e024fd955edf28a3dc87d13745da30e8ac", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00004__wfv__text-contains-paragraph-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF text-contains-paragraph-main-calibration_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "text-contains-paragraph-main-calibration", "sha256": "357aabbb9ef96df7664eeb3699f3b1e024fd955edf28a3dc87d13745da30e8ac", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00004__wfv__text-contains-paragraph-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF text-contains-paragraph-main-calibration_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "text-contains-paragraph-unrelated-header", "sha256": "212be1c5fd0b93a38d4cd982048ff1b345f5232b20301793cbbde220c2a0377b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00006__wfv__text-contains-paragraph-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF text-contains-paragraph-unrelated-header_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "text-contains-paragraph-unrelated-header", "sha256": "212be1c5fd0b93a38d4cd982048ff1b345f5232b20301793cbbde220c2a0377b", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00006__wfv__text-contains-paragraph-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF text-contains-paragraph-unrelated-header_byword.pdf (104002 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "textbox-deleted-text-main", "sha256": "3046841f76c1612d162e18e0eb52ef207c7467ef648f8e908a64d07fbdb541cf", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00008__wfv__textbox-deleted-text-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:07:39.193 'Word found unreadable content in 00008__wfv__textbox-deleted-text-main.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:07:39.717 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00008__wfv__textbox-deleted-text-main...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83c", "pass": 2, "name": "textbox-deleted-text-main", "sha256": "3046841f76c1612d162e18e0eb52ef207c7467ef648f8e908a64d07fbdb541cf", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00008__wfv__textbox-deleted-text-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:08:11.460 'Word found unreadable content in 00008__wfv__textbox-deleted-text-main.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:08:11.963 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00008__wfv__textbox-deleted-text-main...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83c", "pass": 1, "name": "textbox-deleted-text-main-calibration", "sha256": "f39d2f0e8f8c2b73691c4739c357bbaee744765a6933fe415dd50cdc0e6189a0", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00007__wfv__textbox-deleted-text-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF textbox-deleted-text-main-calibration_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "textbox-deleted-text-main-calibration", "sha256": "f39d2f0e8f8c2b73691c4739c357bbaee744765a6933fe415dd50cdc0e6189a0", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00007__wfv__textbox-deleted-text-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF textbox-deleted-text-main-calibration_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "textbox-deleted-text-unrelated-header", "sha256": "5e20e1795aa52ddd33d7671105c78a817ae6230bb066530d29165a185c1e586f", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00009__wfv__textbox-deleted-text-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF textbox-deleted-text-unrelated-header_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "textbox-deleted-text-unrelated-header", "sha256": "5e20e1795aa52ddd33d7671105c78a817ae6230bb066530d29165a185c1e586f", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00009__wfv__textbox-deleted-text-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF textbox-deleted-text-unrelated-header_byword.pdf (23501 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "move-from-deleted-text-main", "sha256": "c66eb457385e0f412039b713458ea0d43e7c2ac0a2cc30739df63efe6a8b1ee6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00001__wfv__move-from-deleted-text-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:07:30.640 'Word found unreadable content in 00001__wfv__move-from-deleted-text-main.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:07:31.147 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__move-from-deleted-text-ma...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83c", "pass": 2, "name": "move-from-deleted-text-main", "sha256": "c66eb457385e0f412039b713458ea0d43e7c2ac0a2cc30739df63efe6a8b1ee6", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00001__wfv__move-from-deleted-text-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:08:02.907 'Word found unreadable content in 00001__wfv__move-from-deleted-text-main.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:08:03.414 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__move-from-deleted-text-ma...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83c", "pass": 1, "name": "move-from-deleted-text-main-calibration", "sha256": "27708437f8db8a5c4d06a56b05d7024cefd924e5d8582eda395882aa3d48356c", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00000__wfv__move-from-deleted-text-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-deleted-text-main-calibration_byword.pdf (7080 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "move-from-deleted-text-main-calibration", "sha256": "27708437f8db8a5c4d06a56b05d7024cefd924e5d8582eda395882aa3d48356c", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00000__wfv__move-from-deleted-text-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-deleted-text-main-calibration_byword.pdf (7080 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "move-from-deleted-text-unrelated-header", "sha256": "dea5c6100fbdd61b6f4bf290365e9a2fa286f77b80d574f87380d47e9e396565", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00002__wfv__move-from-deleted-text-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-deleted-text-unrelated-header_byword.pdf (7080 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "move-from-deleted-text-unrelated-header", "sha256": "dea5c6100fbdd61b6f4bf290365e9a2fa286f77b80d574f87380d47e9e396565", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00002__wfv__move-from-deleted-text-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-deleted-text-unrelated-header_byword.pdf (7080 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 1, "name": "s83c-control-minimal", "sha256": "c23724cc657168b0cfdb8fbdd8e4de954b597186d97479192575d93af5533b39", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:07:48+00:00", "staged": "00003__wfv__s83c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83c", "pass": 2, "name": "s83c-control-minimal", "sha256": "c23724cc657168b0cfdb8fbdd8e4de954b597186d97479192575d93af5533b39", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:23+00:00", "staged": "00003__wfv__s83c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 1, "name": "sdt-id-empty-main", "sha256": "00c1ae4b3f9789cdc20d30730f63f938c1b83ae15282f9bdba9819275f3bf0ff", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00005__wfv__sdt-id-empty-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:08:44.873 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … overy converter.\\n(00005__wfv__sdt-id-empty-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__sdt-id-empty-main.docx; refusing to guess"}
{"run": "s83d", "pass": 2, "name": "sdt-id-empty-main", "sha256": "00c1ae4b3f9789cdc20d30730f63f938c1b83ae15282f9bdba9819275f3bf0ff", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00005__wfv__sdt-id-empty-main.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 09:09:14.431 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … overy converter.\\n(00005__wfv__sdt-id-empty-main.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00005__wfv__sdt-id-empty-main.docx; refusing to guess"}
{"run": "s83d", "pass": 1, "name": "sdt-id-empty-main-calibration", "sha256": "0b87300a94b9d5690a958e1b2e8f194c69c75337b94a2ee3a8d734f12e19afcb", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00004__wfv__sdt-id-empty-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sdt-id-empty-main-calibration_byword.pdf (721672 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 2, "name": "sdt-id-empty-main-calibration", "sha256": "0b87300a94b9d5690a958e1b2e8f194c69c75337b94a2ee3a8d734f12e19afcb", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00004__wfv__sdt-id-empty-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sdt-id-empty-main-calibration_byword.pdf (721672 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 1, "name": "sdt-id-empty-unrelated-header", "sha256": "e2bbd4661852c77d06eb3d8c1f2dc4915dded47a7acb8903b4cdc77e1d38eb13", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00006__wfv__sdt-id-empty-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sdt-id-empty-unrelated-header_byword.pdf (721672 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 2, "name": "sdt-id-empty-unrelated-header", "sha256": "e2bbd4661852c77d06eb3d8c1f2dc4915dded47a7acb8903b4cdc77e1d38eb13", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00006__wfv__sdt-id-empty-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sdt-id-empty-unrelated-header_byword.pdf (721672 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 1, "name": "choice-requires-undeclared-main", "sha256": "04c7580a39bb3768005d191c1daa811c5ff1ccf08a82df393ce37ea0f1d929bd", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00001__wfv__choice-requires-undeclared-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:08:40.272 'Word found unreadable content in 00001__wfv__choice-requires-undeclared-main.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:08:40.767 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__choice-requires-undeclare...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83d", "pass": 2, "name": "choice-requires-undeclared-main", "sha256": "04c7580a39bb3768005d191c1daa811c5ff1ccf08a82df393ce37ea0f1d929bd", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00001__wfv__choice-requires-undeclared-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 09:09:10.122 'Word found unreadable content in 00001__wfv__choice-requires-undeclared-main.docx. Do you want to r … ? If you trust the source of this document, click Yes.'", "2026-10-28 09:09:10.647 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__choice-requires-undeclare...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s83d", "pass": 1, "name": "choice-requires-undeclared-main-calibration", "sha256": "3b8a895d745a7516e3c45eb92ac044d770aeadde49716e1c34e665b88c261a32", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00000__wfv__choice-requires-undeclared-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-requires-undeclared-main-calibration_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 2, "name": "choice-requires-undeclared-main-calibration", "sha256": "3b8a895d745a7516e3c45eb92ac044d770aeadde49716e1c34e665b88c261a32", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00000__wfv__choice-requires-undeclared-main-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-requires-undeclared-main-calibration_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 1, "name": "choice-requires-undeclared-unrelated-header", "sha256": "8aeee434603a730fd0c5eb51daae77f12d521335f688b077d3aeded0bbed1357", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00002__wfv__choice-requires-undeclared-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-requires-undeclared-unrelated-header_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 2, "name": "choice-requires-undeclared-unrelated-header", "sha256": "8aeee434603a730fd0c5eb51daae77f12d521335f688b077d3aeded0bbed1357", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00002__wfv__choice-requires-undeclared-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-requires-undeclared-unrelated-header_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 1, "name": "s83d-control-minimal", "sha256": "a7fde1a84a917de2ba3ed35197c1f846f6b33307a59f6c29f499474774d0a4d3", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:08:54+00:00", "staged": "00003__wfv__s83d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s83d", "pass": 2, "name": "s83d-control-minimal", "sha256": "a7fde1a84a917de2ba3ed35197c1f846f6b33307a59f6c29f499474774d0a4d3", "validatorRevision": "568d746adf4aaa478735b82672c3bbd66c858355", "observedAt": "2026-10-28T13:09:24+00:00", "staged": "00003__wfv__s83d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s83d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 83 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.

`s83builder.mts`:

```ts
// Session 83 (2026-10-28): which parts Word judges the by-name story rules' shapes in (#1113).
// Twenty check files walk `ctx.storyParts()`, the parts named like a story wherever stored, not the parts Word reads.
// Session 82 (#1106) showed the cost for `word-hyperlink-relationship`: Word refused its shape in a main document stored
// as word/main.xml and opened it clean in an unrelated word/header9.xml. This session asks the same of the Word-blocking
// rules whose refused shape session 41 attributes to one fixture pair (a broken fixture Word refused, a twin it opened
// clean). For each pair, three rows:
// - `<rule>-main`: the broken fixture with its main document stored as word/main.xml (_rels/.rels, the content-types
//   Override and the sidecar's name follow), whose shape the by-name list does not judge;
// - `<rule>-main-calibration`: the clean twin renamed the same way;
// - `<rule>-unrelated-header`: the clean twin plus word/header83.xml (session 82 used header9, which one fixture
//   stores), typed header by its Override, which no relationship names,
//   holding the broken main document's body (its w:sectPr elements dropped) under a w:hdr root with the document root's
//   attributes, and a copy of the broken main document's relationships as its sidecar. The by-name list judges it.
// Each pair's broken fixture must hold the rule's finding in word/document.xml (the builder checks it), so session 41's
// word-textbox-deleted-text pair is its `-shape` one: the plain fixture's defect sits in footer1.xml.
// Every row records the validator revision it was judged at (`validatorRevision`); the verdict helper is s82builder.mts's.
// The builder empties the chunk's specimens.jsonl once before its row loop (promised on #825), and its src (#985).
// Run from a worktree root: CHUNK=s83a pnpm exec node --import tsx <this file>
// (the imports are absolute, so the file needs no copy into the worktree; `git rev-parse` reads the cwd's worktree).
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { createRequire } from "node:module";
import { appendFileSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { parseXml } = await import(path.join(WT, "src/lib/xml-helpers.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const JSZip = createRequire(path.join(WT, "package.json"))("jszip");
const REVISION = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const FIXTURES = path.join(WT, "tests/fixtures");

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const MAIN_RELS = "word/_rels/document.xml.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;

const replaceOnce = (text: string, from: string | RegExp, to: string) => {
    const count = typeof from === "string" ? text.split(from).length - 1 : (text.match(new RegExp(from.source, "g")) ?? []).length;
    if (count !== 1) throw new Error(`expected exactly one ${from}, found ${count}`);
    return text.replace(from, to);
};

type Parts = Map<string, Uint8Array>;
const utf8 = new TextDecoder("utf-8");
const encoder = new TextEncoder();
const textOf = (parts: Parts, name: string) => {
    const bytes = parts.get(name);
    if (!bytes) throw new Error(`no ${name}`);
    const text = utf8.decode(bytes);
    return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
};

/** The fixture's parts in stored order. */
const load = async (rel: string): Promise<Parts> => {
    const zip = await JSZip.loadAsync(readFileSync(path.join(FIXTURES, rel)));
    const parts: Parts = new Map();
    for (const name of Object.keys(zip.files)) {
        if (!zip.files[name].dir) parts.set(name, await zip.files[name].async("uint8array"));
    }
    return parts;
};
const pack = async (parts: Parts): Promise<Uint8Array> => {
    const zip = new JSZip();
    for (const [name, bytes] of parts) zip.file(name, bytes, { compression: "DEFLATE" });
    return zip.generateAsync({ type: "uint8array", compression: "DEFLATE" });
};

/** The package with its main document stored as word/main.xml; every name that points at it follows. */
const renameMain = (parts: Parts): Parts => {
    if (!parts.has(MAIN)) throw new Error("no word/document.xml");
    const out: Parts = new Map();
    for (const [name, bytes] of parts) {
        if (name === MAIN) out.set("word/main.xml", bytes);
        else if (name === MAIN_RELS) out.set("word/_rels/main.xml.rels", bytes);
        else if (name === "_rels/.rels")
            out.set(
                name,
                encoder.encode(replaceOnce(textOf(parts, name), /Target="(\/?)word\/document\.xml"/, 'Target="$1word/main.xml"')),
            );
        else if (name === CT)
            out.set(name, encoder.encode(replaceOnce(textOf(parts, name), 'PartName="/word/document.xml"', 'PartName="/word/main.xml"')));
        else out.set(name, bytes);
    }
    return out;
};

/** `text` without its outermost `<tag>` elements, nested ones (a w:sectPr inside a w:sectPrChange) counted, not matched. */
const withoutElements = (text: string, tag: string): string => {
    const token = new RegExp(`<${tag}\\b[^>]*?(/?)>|</${tag}>`, "g");
    let out = "";
    let depth = 0;
    let start = 0;
    let cut = 0;
    for (let match = token.exec(text); match; match = token.exec(text)) {
        const closing = match[0].startsWith("</");
        const selfClosing = !closing && match[1] === "/";
        if (depth === 0 && !closing) {
            out += text.slice(cut, match.index);
            start = match.index;
            if (selfClosing) {
                cut = token.lastIndex;
                continue;
            }
            depth = 1;
        } else if (closing) {
            depth -= 1;
            if (depth < 0) throw new Error(`unbalanced </${tag}>`);
            if (depth === 0) cut = token.lastIndex;
        } else if (!selfClosing) {
            depth += 1;
        }
    }
    if (depth !== 0) throw new Error(`unclosed <${tag}> at ${start}`);
    return out + text.slice(cut);
};

/** `broken`'s main-document body as a header part: the w:document root's attributes on w:hdr, its w:sectPr elements dropped. */
const bodyAsHeader = (doc: string): string => {
    const attributes = doc.match(/<w:document\b([^>]*)>/)?.[1];
    const body = doc.match(/<w:body>([\s\S]*)<\/w:body>/)?.[1];
    if (attributes === undefined || body === undefined) throw new Error("no w:document root or w:body");
    const inner = withoutElements(body, "w:sectPr");
    if (!/<w:(p|tbl|sdt)\b/.test(inner)) throw new Error("the body holds no block-level content");
    const header = `${XML_DECL}<w:hdr${attributes}>${inner}</w:hdr>`;
    parseXml(header);
    return header;
};

const UNRELATED = "header83.xml";
/** The clean twin plus word/header83.xml, typed header and named by no relationship, holding the broken body. */
const withUnrelatedHeader = (clean: Parts, broken: Parts): Parts => {
    if ([...clean.keys()].some((name) => name.toLowerCase().includes(UNRELATED))) throw new Error(`the twin already stores ${UNRELATED}`);
    const out: Parts = new Map(clean);
    out.set(
        CT,
        encoder.encode(
            replaceOnce(textOf(clean, CT), "</Types>", `<Override PartName="/word/${UNRELATED}" ContentType="${WML}.header+xml"/></Types>`),
        ),
    );
    out.set(`word/${UNRELATED}`, encoder.encode(bodyAsHeader(textOf(broken, MAIN))));
    out.set(`word/_rels/${UNRELATED}.rels`, broken.get(MAIN_RELS)!);
    return out;
};

/** Session 41's pairs: the rule, the fixture Word refused, and the twin it opened clean. */
const PAIRS: Record<string, [string, string, string]> = {
    "row-without-cell": [
        "word-row-without-cell",
        "broken/package.word-row-without-cell.docx",
        "working/package.word-row-without-cell-repaired.docx",
    ],
    "cell-ends-with-table": [
        "word-cell-ends-with-table",
        "broken/package.word-cell-ends-with-table.docx",
        "working/package.word-cell-ends-with-table-repaired.docx",
    ],
    "arc-radius": ["word-drawing-arc-radius", "broken/package.drawing-arc-radius.docx", "working/package.drawing-arc-radius-integer.docx"],
    "extent-negative": [
        "word-drawing-extent-negative",
        "broken/package.word-drawing-extent-negative.docx",
        "working/package.word-drawing-extent-positive.docx",
    ],
    "empty-drawing": ["word-empty-drawing", "broken/package.word-empty-drawing.docx", "working/package.word-empty-drawing-removed.docx"],
    "anchor-open": [
        "word-anchor-missing-attribute",
        "broken/package.word-anchor-open.docx",
        "working/package.word-anchor-open-repaired.docx",
    ],
    "text-contains-paragraph": [
        "word-text-contains-paragraph",
        "broken/package.word-text-contains-paragraph.docx",
        "working/package.word-text-contains-paragraph-lifted.docx",
    ],
    "textbox-deleted-text": [
        "word-textbox-deleted-text",
        "broken/package.word-textbox-deleted-text-shape.docx",
        "working/package.word-textbox-deleted-text-shape-repaired.docx",
    ],
    "move-from-deleted-text": [
        "word-move-from-deleted-text",
        "broken/package.word-move-from-deleted-text.docx",
        "working/package.word-move-from-text.docx",
    ],
    "sdt-id-empty": ["word-sdt-id-empty", "broken/package.word-sdt-id-empty.docx", "working/package.word-sdt-id-empty-repaired.docx"],
    "choice-requires-undeclared": [
        "word-choice-requires-undeclared",
        "broken/package.word-choice-requires-undeclared.docx",
        "working/package.word-choice-requires-declared.docx",
    ],
};

type Row = [string, string, () => Promise<Uint8Array>];
/** The three rows for one pair. */
const rowsFor = (key: string): Row[] => {
    const [rule, broken, clean] = PAIRS[key]!;
    return [
        [
            `${key}-main`,
            `#1113 ${rule}: ${broken} with its main document stored as word/main.xml`,
            async () => pack(renameMain(await load(broken))),
        ],
        [`${key}-main-calibration`, `calibration: ${clean} renamed the same way`, async () => pack(renameMain(await load(clean)))],
        [
            `${key}-unrelated-header`,
            `#1113 ${rule}: ${clean} plus an unrelated word/${UNRELATED} holding ${broken}'s body`,
            async () => pack(withUnrelatedHeader(await load(clean), await load(broken))),
        ],
    ];
};
const control = () => buildDocx({ ...(MINIMAL_PARTS as Record<string, string>) });
const withControl = (chunk: string, keys: string[]): Row[] => [...keys.flatMap(rowsFor), [`${chunk}-control-minimal`, "control", control]];

const chunks: Record<string, Row[]> = {
    s83a: withControl("s83a", ["row-without-cell", "cell-ends-with-table", "arc-radius"]),
    s83b: withControl("s83b", ["extent-negative", "empty-drawing", "anchor-open"]),
    s83c: withControl("s83c", ["text-contains-paragraph", "textbox-deleted-text", "move-from-deleted-text"]),
    s83d: withControl("s83d", ["sdt-id-empty", "choice-requires-undeclared"]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const key of Object.keys(PAIRS)) {
    if (!specimens.some(([name]) => name.startsWith(`${key}-`))) continue;
    const [rule, broken] = PAIRS[key]!;
    const found = (await validate(path.join(FIXTURES, broken), { profile: "word-valid" })).issues.filter(
        (x: { code: string }) => x.code === rule,
    );
    if (found.length === 0 || found.some((x: { path?: string }) => x.path !== MAIN))
        throw new Error(`${broken}: ${rule} is not only in ${MAIN}`);
}

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-83 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s83a", "s83b", "s83c", "s83d")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s83/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-83 parts of docs/plans/evidence/word-probes-2026-10-24.md into s83/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s83a", "s83b", "s83c", "s83d")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s83/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def strict_cell(v):
    # Strict also reports the fixtures' own paraId, XSD and unreferenced-part findings; leave those out and name every
    # other code with its part, so the column shows whether strict judged the probed rule. The fixtures' other findings,
    # such as textid-missing-element, stay in the column (#1124).
    if v["valid"] is None:
        return cell(v)
    noise = ("rels-unreferenced@", "paraid-missing-element@", "xsd-summary@", "xsd-error@")
    rules = [e for e in v["errors"] if not e.startswith(noise)]
    if v["valid"]:
        return "valid"
    return "invalid: " + (", ".join(f"`{e}`" for e in rules) if rules else "fixture findings only")


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {strict_cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            record = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                      "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                      "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                      "pdf": row["pdf"], "evidence": row["evidence"]}
            error = manifest(r, s["file"]).get("error")
            if error:
                record["error"] = error
            raw.append(json.dumps(record, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

KEYS = ("row-without-cell", "cell-ends-with-table", "arc-radius", "extent-negative", "empty-drawing", "anchor-open",
        "text-contains-paragraph", "textbox-deleted-text", "move-from-deleted-text", "sdt-id-empty", "choice-requires-undeclared")
REFUSED = {f"{k}-main.docx" for k in KEYS}
UNRELATED = {f"{k}-unrelated-header.docx" for k in KEYS}
# word-valid at the probed revision misses every renamed main document but one (mce-malformed judges every part, so it
# rejects the renamed choice-requires row), and rejects every unrelated header.
CAUGHT = {"choice-requires-undeclared-main.docx"}
# The narrative's claims about outcomes, checked against results.json: every row's four readings agree, the renamed main
# documents were refused and every other row opened clean, and word-valid at the probed revision gets exactly the
# renamed main documents it passes and the unrelated headers wrong.
for (label, file), r in results.items():
    assert r["agreed"], (label, file, r)
    if file in REFUSED:
        assert r["everyReadingRejects"], (label, file, r)
    else:
        assert set(r["readings"]) == {"clean-open"}, (label, file, r)
    assert r["wordValid"] is ((file not in CAUGHT) and file not in UNRELATED), (label, file, r)
    assert r["validatorMatchesWord"] is (file not in (REFUSED - CAUGHT) | UNRELATED), (label, file, r)
assert agreed == len(rows) == 37, (agreed, len(rows))
assert {f for (_, f) in results} >= REFUSED | UNRELATED
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == files, (run, opened)
# The text Word rendered, both runs: each unrelated header renders exactly what its main-document calibration renders
# (both are the clean twin; Word did not read header83), each control renders "Hello", and a refused row left no PDF.
texts = {}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
            file = json.loads(line)["original_filename"]
            text = rendered(run, file)
            texts.setdefault(file, set()).add(text)
            if file in REFUSED:
                assert text is None, (run, file, text)
            else:
                assert text is not None, (run, file)
for key in KEYS:
    assert texts[f"{key}-unrelated-header.docx"] == texts[f"{key}-main-calibration.docx"], key
    assert len(texts[f"{key}-main-calibration.docx"]) == 1, key
for label in CHUNKS:
    assert texts[f"{label}-control-minimal.docx"] == {"Hello"}, (label, texts[f"{label}-control-minimal.docx"])
textless = sorted(k for k in KEYS if texts[f"{k}-main-calibration.docx"] == {""})
assert textless == ["choice-requires-undeclared", "empty-drawing"], textless
RULES = {"row-without-cell": "word-row-without-cell", "cell-ends-with-table": "word-cell-ends-with-table",
         "arc-radius": "word-drawing-arc-radius", "extent-negative": "word-drawing-extent-negative",
         "empty-drawing": "word-empty-drawing", "anchor-open": "word-anchor-missing-attribute",
         "text-contains-paragraph": "word-text-contains-paragraph", "textbox-deleted-text": "word-textbox-deleted-text",
         "move-from-deleted-text": "word-move-from-deleted-text", "sdt-id-empty": "word-sdt-id-empty",
         "choice-requires-undeclared": "word-choice-requires-undeclared"}
outcome_of = {f: r["outcome"] for (_, f), r in results.items()}
OPEN_ERROR = [k for k in KEYS if outcome_of[f"{k}-main.docx"] == "open-error"]
WARNED = [k for k in KEYS if outcome_of[f"{k}-main.docx"] == "unreadable-content-warning"]
assert len(OPEN_ERROR) + len(WARNED) == len(KEYS), (OPEN_ERROR, WARNED)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 83: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Whether Word judges [#1113](https://github.com/jandira-tech/docx-validate/issues/1113)'s Word-blocking rules in the "
    "parts it reads, as session 82 found for the hyperlink relationship. Twenty check files, holding 26 Word rules, judge "
    "the parts named like a story wherever stored (`STORY_PART`), not the parts Word reads. Eleven of those rules, in "
    "eight of the files, have a Word-refused fixture "
    "whose finding is only in `word/document.xml` and a clean twin (session 41's pairs; the `-shape` pair for "
    "`word-textbox-deleted-text`, whose plain fixture holds its defect in a footer). Each pair gives three rows: `-main` is "
    "the broken fixture with its main document stored as `word/main.xml`, with `_rels/.rels`, the content-types Override "
    "and the part's own relationships following the name; `-main-calibration` is the clean twin renamed the same way; "
    "`-unrelated-header` is the clean twin plus `word/header83.xml`, typed header by its Override, which no relationship "
    "names, holding the broken fixture's body under a `w:hdr` root with its `w:sectPr` removed, and the broken main "
    "document's relationships as its own. Chunk s83a holds `word-row-without-cell`, `word-cell-ends-with-table` and "
    "`word-drawing-arc-radius`; s83b `word-drawing-extent-negative`, `word-empty-drawing` and "
    "`word-anchor-missing-attribute`; s83c `word-text-contains-paragraph`, `word-textbox-deleted-text` and "
    "`word-move-from-deleted-text`; s83d `word-sdt-id-empty` and `word-choice-requires-undeclared`. Each chunk ends with "
    "a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows "
    "were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the "
    f"manifest spelling when both runs and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows "
    "agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of "
    f"the specimen. The builder recorded the validator revision in every row (`{rev}`). The strict column leaves out the "
    "`rels-unreferenced`, `paraid-missing-element`, `xsd-summary` and `xsd-error` findings and names every other strict "
    "error, so beside the probed rule it also names fixture findings such as `textid-missing-element` and "
    "`style-default-missing` (#1124).",
    "",
    "Every calibration and control opened clean. Each unrelated header's PDF holds exactly its calibration's text in "
    "both runs (`pdftotext`; the `word-empty-drawing` and `word-choice-requires-undeclared` twins render no text), and "
    "each control's holds `Hello`. No refused row left a PDF.",
    "",
    "- **Word judges the eleven shapes in a main document whatever its name.** It refused all eleven renamed main "
    f"documents, as it did in `word/document.xml` (session 41): an open error for {len(OPEN_ERROR)} "
    f"({', '.join(f'`{RULES[k]}`' for k in OPEN_ERROR)}) and an offer to recover unreadable content for "
    f"{len(WARNED)} ({', '.join(f'`{RULES[k]}`' for k in WARNED)}).",
    "- **It does not judge them in a part it does not read.** It opened every shape clean in the unrelated "
    "`word/header83.xml`, as the read model says it reads no part that no relationship names (#726).",
    "",
    f"Word-valid at {at} judged by name, so it matches Word on {matches} of {len(rows)} rows: it passes ten of the "
    "renamed main documents and rejects all eleven unrelated headers. It rejects the renamed "
    "`word-choice-requires-undeclared` row only through `mce-malformed`, which judges every part: that rule also rejects "
    "the unrelated header Word opened clean. "
    "[#1113](https://github.com/jandira-tech/docx-validate/issues/1113) moves the rules onto the read model.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 83</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 83 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged.",
    "",
]
for name, path, lang in (("s83builder.mts", ROOT / "s83builder.mts", "ts"), ("compare.py", ROOT / "s83/compare.py", "python"),
                         ("section.py", ROOT / "s83/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s83/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 84: 14:01Z–14:01Z on 2026-10-28, validator columns at 51288228

Whether Word judges markup compatibility in a `word/` part it does not read ([#1116](https://github.com/jandira-tech/docx-validate/issues/1116)). Session 83 (s83d) opened clean an undeclared-`Requires` Choice (`mce-malformed`) in a `word/header83.xml` that no relationship names, and refused it in a main document stored as `word/main.xml`. `mce-must-understand` in such a part was unprobed, and #639's rows pinned it blocking in a stray `word/foo.xml`. One chunk, s84a, mostly on the minimal package:

- `mu-unrelated-header` adds `word/header83.xml`, typed header by its Override and named by no relationship, whose `w:hdr` root carries `mc:MustUnderstand="foo"` for an unknown `urn:foo`; its `-calibration` drops the attribute;
- `mu-stray-foo` is #639's specimen, `word/foo.xml` with no Override and no relationship, a `w:document` root carrying the same attribute around an empty body, with its `-calibration`;
- `mu-used-header` has the main document relate the header and the body's `w:sectPr` reference it, and `mu-unused-header` has it related and referenced by nothing;
- `mu-main` puts the attribute on the main document's root;
- `choice-unused-header` is session 83's `choice-requires-undeclared-unrelated-header` with the main document relating the header and nothing referencing it.

The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 9 of 9 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`51288228dfe6ca4454d16562ec0a4798364614ab`), judging an export of that commit. The strict column names only the markup-compatibility findings.

Every calibration and the control opened clean. Every row Word opened renders the main document's `Hello` in both runs (`pdftotext`), never the header's `Header 84`; the Choice row renders no text, as its clean twin did in session 83. No refused row left a PDF.

- **Word refuses an unknown `mc:MustUnderstand` in a part it reads.** It offered to recover unreadable content for the main document's root and for a header the body references.
- **It does not judge it in a part no relationship names.** It opened clean the unrelated header and #639's stray `word/foo.xml`, as it opened session 83's Choice there.
- **Nor in a header the main document relates but does not use.** It opened clean the related, unreferenced header holding the attribute and the one holding session 83's Choice.

Word-valid at 51288228 matches Word on 5 of 9 rows: it rejects the four clean rows that hold a finding. #1116 makes both findings warn in a `word/` part no relationship names, so it passes `mu-unrelated-header` and `mu-stray-foo`; [#1125](https://github.com/jandira-tech/docx-validate/issues/1125) covers the two related, unused headers.

| Run    | Observed             | Specimen                          | Shape                                                                                                                                                                                                                  | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 51288228                           | strict at 51288228                               |
| ------ | -------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------------ | ------------------------------------------------ |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-unrelated-header`             | #1116 mce-must-understand: minimal plus word/header83.xml, typed header, named by no relationship, root MustUnderstand urn:foo                                                                                         | `ee9f112a5b639c87` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/header83.xml` | invalid: `mce-must-understand@word/header83.xml` |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-unrelated-header-calibration` | calibration: the same header without MustUnderstand                                                                                                                                                                    | `627df9bbca283a46` | clean-open     | clean-open     | clean-open                 | valid                                            | invalid: no markup-compatibility finding         |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-stray-foo`                    | #1116/#639 mce-must-understand: minimal plus word/foo.xml (no Override, no relationship), w:document root MustUnderstand urn:foo                                                                                       | `07c881cba45e22f7` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/foo.xml`      | invalid: `mce-must-understand@word/foo.xml`      |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-stray-foo-calibration`        | calibration: the same word/foo.xml without MustUnderstand                                                                                                                                                              | `025199ec85e23ca5` | clean-open     | clean-open     | clean-open                 | valid                                            | invalid: no markup-compatibility finding         |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-used-header`                  | #1116 mce-must-understand: the header related by the main document and referenced by its w:sectPr                                                                                                                      | `24f000b5d34a4327` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/header83.xml` | invalid: `mce-must-understand@word/header83.xml` |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-unused-header`                | #1116 mce-must-understand: the header related by the main document, referenced by nothing                                                                                                                              | `f7d49286c122f3c5` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/header83.xml` | invalid: `mce-must-understand@word/header83.xml` |
| `s84a` | 14:01:31Z, 14:01:52Z | `mu-main`                         | #1116 mce-must-understand: the main document's root carrying MustUnderstand urn:foo                                                                                                                                    | `cfd182457fc182bc` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/document.xml` | invalid: `mce-must-understand@word/document.xml` |
| `s84a` | 14:01:31Z, 14:01:52Z | `choice-unused-header`            | #1116 mce-malformed: working/package.word-choice-requires-declared.docx plus word/header83.xml holding broken/package.word-choice-requires-undeclared.docx's body, related by the main document, referenced by nothing | `7b8102df5ab932bd` | clean-open     | clean-open     | clean-open                 | invalid: `mce-malformed@word/header83.xml`       | invalid: `mce-malformed@word/header83.xml`       |
| `s84a` | 14:01:31Z, 14:01:52Z | `s84a-control-minimal`            | control                                                                                                                                                                                                                | `28ac679cc2c418f3` | clean-open     | clean-open     | clean-open                 | valid                                            | valid                                            |

<details><summary>Raw records, session 84</summary>

```jsonl
{"run": "s84a", "pass": 1, "name": "mu-unrelated-header", "sha256": "ee9f112a5b639c879e7f34fd5a2626012ffbc32ac69cad533142b09bb21fae3d", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00005__wfv__mu-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unrelated-header_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "mu-unrelated-header", "sha256": "ee9f112a5b639c879e7f34fd5a2626012ffbc32ac69cad533142b09bb21fae3d", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00005__wfv__mu-unrelated-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unrelated-header_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "mu-unrelated-header-calibration", "sha256": "627df9bbca283a467b5b696d1c5ca7f14b5b915271cf5904bd8ded3c2de60b75", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00004__wfv__mu-unrelated-header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unrelated-header-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "mu-unrelated-header-calibration", "sha256": "627df9bbca283a467b5b696d1c5ca7f14b5b915271cf5904bd8ded3c2de60b75", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00004__wfv__mu-unrelated-header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unrelated-header-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "mu-stray-foo", "sha256": "07c881cba45e22f7f333f7d7b0863f7d0b0d111fecb4a3d4f77cfcac16abf343", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00003__wfv__mu-stray-foo.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "mu-stray-foo", "sha256": "07c881cba45e22f7f333f7d7b0863f7d0b0d111fecb4a3d4f77cfcac16abf343", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00003__wfv__mu-stray-foo.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "mu-stray-foo-calibration", "sha256": "025199ec85e23ca5c61e32a7325e61508f233f0752547b30c8b1a83e32048365", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00002__wfv__mu-stray-foo-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "mu-stray-foo-calibration", "sha256": "025199ec85e23ca5c61e32a7325e61508f233f0752547b30c8b1a83e32048365", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00002__wfv__mu-stray-foo-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "mu-used-header", "sha256": "24f000b5d34a43271313ac120fb4660e447b06cae0d3468762e8ee995fcbfa1f", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00007__wfv__mu-used-header.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 10:01:30.316 'Word found unreadable content in 00007__wfv__mu-used-header.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-28 10:01:30.824 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00007__wfv__mu-used-header.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s84a", "pass": 2, "name": "mu-used-header", "sha256": "24f000b5d34a43271313ac120fb4660e447b06cae0d3468762e8ee995fcbfa1f", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00007__wfv__mu-used-header.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 10:01:51.148 'Word found unreadable content in 00007__wfv__mu-used-header.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.'", "2026-10-28 10:01:51.656 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  Recovery converter. (00007__wfv__mu-used-header.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s84a", "pass": 1, "name": "mu-unused-header", "sha256": "f7d49286c122f3c58a664e1bbe7fe9fa790a9857ab03c5c98d46a7168988988d", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00006__wfv__mu-unused-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unused-header_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "mu-unused-header", "sha256": "f7d49286c122f3c58a664e1bbe7fe9fa790a9857ab03c5c98d46a7168988988d", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00006__wfv__mu-unused-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-unused-header_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "mu-main", "sha256": "cfd182457fc182bcf10741fbea29842c0cf1a00d2cf87b2c1f37bcb24ab8eba8", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00001__wfv__mu-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 10:01:26.031 'Word found unreadable content in 00001__wfv__mu-main.docx. Do you want to recover the contents of t … ? If you trust the source of this document, click Yes.'", "2026-10-28 10:01:26.522 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … he Text Recovery converter. (00001__wfv__mu-main.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s84a", "pass": 2, "name": "mu-main", "sha256": "cfd182457fc182bcf10741fbea29842c0cf1a00d2cf87b2c1f37bcb24ab8eba8", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00001__wfv__mu-main.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 10:01:46.848 'Word found unreadable content in 00001__wfv__mu-main.docx. Do you want to recover the contents of t … ? If you trust the source of this document, click Yes.'", "2026-10-28 10:01:47.373 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … he Text Recovery converter. (00001__wfv__mu-main.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s84a", "pass": 1, "name": "choice-unused-header", "sha256": "7b8102df5ab932bd5f35a6155206aac8c65a9dde1172d55a2e20932b4c77ae95", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00000__wfv__choice-unused-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-unused-header_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "choice-unused-header", "sha256": "7b8102df5ab932bd5f35a6155206aac8c65a9dde1172d55a2e20932b4c77ae95", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00000__wfv__choice-unused-header.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF choice-unused-header_byword.pdf (11571 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 1, "name": "s84a-control-minimal", "sha256": "28ac679cc2c418f3abf3aa8425d1e7f7483b7241f2db5ef4db736866ff8165ce", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:31+00:00", "staged": "00008__wfv__s84a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s84a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s84a", "pass": 2, "name": "s84a-control-minimal", "sha256": "28ac679cc2c418f3abf3aa8425d1e7f7483b7241f2db5ef4db736866ff8165ce", "validatorRevision": "51288228dfe6ca4454d16562ec0a4798364614ab", "observedAt": "2026-10-28T14:01:52+00:00", "staged": "00008__wfv__s84a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s84a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 84 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. The builder ran on an export of the recorded revision (`git archive`), `node_modules` linked in, with `WT` and `REVISION` naming them.

`s84builder.mts`:

```ts
// Session 84 (2026-10-28): does Word read markup compatibility in a word/ part no relationship names (#1116)?
// Session 83 (s83d) opened clean an undeclared-Requires Choice (`mce-malformed`) in an unrelated word/header83.xml and
// refused it in a main document stored as word/main.xml. #1116 lets `mce-malformed` and `mce-must-understand` warn in a
// word/ part no relationship names; `mce-must-understand` there is unprobed, and #639's rows pin it blocking in a stray
// word/foo.xml. Rows, on the minimal package (`tests/support/minimal-docx.ts`) unless named otherwise:
// - `mu-unrelated-header`: word/header83.xml, typed header by its Override, named by no relationship, whose w:hdr root
//   carries mc:MustUnderstand="foo" for an unknown urn:foo; its `-calibration` drops the attribute;
// - `mu-stray-foo`: #639's specimen, word/foo.xml with no Override and no relationship, a w:document root carrying the
//   same MustUnderstand and an empty body; its `-calibration` drops the attribute;
// - `mu-used-header`: the header related by the main document and referenced by its w:sectPr, the read placement;
// - `mu-unused-header`: the header related by the main document, referenced by nothing (unprobed for these findings);
// - `mu-main`: the main document's root carrying the MustUnderstand;
// - `choice-unused-header`: s83d's `choice-requires-undeclared-unrelated-header` with the main document relating the
//   header and nothing referencing it (`mce-malformed` in a related, unused part, unprobed);
// - a minimal control.
// Every row records the validator revision it was judged at (`validatorRevision`).
// Run: WT=<exported tree> REVISION=<its commit> CHUNK=s84a tsx <this file>
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { createRequire } from "node:module";
import { appendFileSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
// WT names an exported tree (no .git), REVISION the commit it was exported at.
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { parseXml } = await import(path.join(WT, "src/lib/xml-helpers.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const JSZip = createRequire(path.join(WT, "package.json"))("jszip");
const REVISION = process.env.REVISION ?? execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const FIXTURES = path.join(WT, "tests/fixtures");

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const MAIN_RELS = "word/_rels/document.xml.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;

const replaceOnce = (text: string, from: string | RegExp, to: string) => {
    const count = typeof from === "string" ? text.split(from).length - 1 : (text.match(new RegExp(from.source, "g")) ?? []).length;
    if (count !== 1) throw new Error(`expected exactly one ${from}, found ${count}`);
    return text.replace(from, to);
};

type Parts = Map<string, Uint8Array>;
const utf8 = new TextDecoder("utf-8");
const encoder = new TextEncoder();
const textOf = (parts: Parts, name: string) => {
    const bytes = parts.get(name);
    if (!bytes) throw new Error(`no ${name}`);
    const text = utf8.decode(bytes);
    return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
};

/** The fixture's parts in stored order. */
const load = async (rel: string): Promise<Parts> => {
    const zip = await JSZip.loadAsync(readFileSync(path.join(FIXTURES, rel)));
    const parts: Parts = new Map();
    for (const name of Object.keys(zip.files)) {
        if (!zip.files[name].dir) parts.set(name, await zip.files[name].async("uint8array"));
    }
    return parts;
};
const pack = async (parts: Parts): Promise<Uint8Array> => {
    const zip = new JSZip();
    for (const [name, bytes] of parts) zip.file(name, bytes, { compression: "DEFLATE" });
    return zip.generateAsync({ type: "uint8array", compression: "DEFLATE" });
};

/** The package with its main document stored as word/main.xml; every name that points at it follows. */
const renameMain = (parts: Parts): Parts => {
    if (!parts.has(MAIN)) throw new Error("no word/document.xml");
    const out: Parts = new Map();
    for (const [name, bytes] of parts) {
        if (name === MAIN) out.set("word/main.xml", bytes);
        else if (name === MAIN_RELS) out.set("word/_rels/main.xml.rels", bytes);
        else if (name === "_rels/.rels")
            out.set(
                name,
                encoder.encode(replaceOnce(textOf(parts, name), /Target="(\/?)word\/document\.xml"/, 'Target="$1word/main.xml"')),
            );
        else if (name === CT)
            out.set(name, encoder.encode(replaceOnce(textOf(parts, name), 'PartName="/word/document.xml"', 'PartName="/word/main.xml"')));
        else out.set(name, bytes);
    }
    return out;
};

/** `text` without its outermost `<tag>` elements, nested ones (a w:sectPr inside a w:sectPrChange) counted, not matched. */
const withoutElements = (text: string, tag: string): string => {
    const token = new RegExp(`<${tag}\\b[^>]*?(/?)>|</${tag}>`, "g");
    let out = "";
    let depth = 0;
    let start = 0;
    let cut = 0;
    for (let match = token.exec(text); match; match = token.exec(text)) {
        const closing = match[0].startsWith("</");
        const selfClosing = !closing && match[1] === "/";
        if (depth === 0 && !closing) {
            out += text.slice(cut, match.index);
            start = match.index;
            if (selfClosing) {
                cut = token.lastIndex;
                continue;
            }
            depth = 1;
        } else if (closing) {
            depth -= 1;
            if (depth < 0) throw new Error(`unbalanced </${tag}>`);
            if (depth === 0) cut = token.lastIndex;
        } else if (!selfClosing) {
            depth += 1;
        }
    }
    if (depth !== 0) throw new Error(`unclosed <${tag}> at ${start}`);
    return out + text.slice(cut);
};

/** `broken`'s main-document body as a header part: the w:document root's attributes on w:hdr, its w:sectPr elements dropped. */
const bodyAsHeader = (doc: string): string => {
    const attributes = doc.match(/<w:document\b([^>]*)>/)?.[1];
    const body = doc.match(/<w:body>([\s\S]*)<\/w:body>/)?.[1];
    if (attributes === undefined || body === undefined) throw new Error("no w:document root or w:body");
    const inner = withoutElements(body, "w:sectPr");
    if (!/<w:(p|tbl|sdt)\b/.test(inner)) throw new Error("the body holds no block-level content");
    const header = `${XML_DECL}<w:hdr${attributes}>${inner}</w:hdr>`;
    parseXml(header);
    return header;
};

const UNRELATED = "header83.xml";
/** The clean twin plus word/header83.xml, typed header and named by no relationship, holding the broken body. */
const withUnrelatedHeader = (clean: Parts, broken: Parts): Parts => {
    if ([...clean.keys()].some((name) => name.toLowerCase().includes(UNRELATED))) throw new Error(`the twin already stores ${UNRELATED}`);
    const out: Parts = new Map(clean);
    out.set(
        CT,
        encoder.encode(
            replaceOnce(textOf(clean, CT), "</Types>", `<Override PartName="/word/${UNRELATED}" ContentType="${WML}.header+xml"/></Types>`),
        ),
    );
    out.set(`word/${UNRELATED}`, encoder.encode(bodyAsHeader(textOf(broken, MAIN))));
    out.set(`word/_rels/${UNRELATED}.rels`, broken.get(MAIN_RELS)!);
    return out;
};

const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const MU = `xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo"`;
const minimal = (): Parts =>
    new Map(Object.entries(MINIMAL_PARTS as Record<string, string>).map(([name, text]) => [name, encoder.encode(text)]));
const headerXml = (mustUnderstand: boolean) =>
    `${XML_DECL}<w:hdr xmlns:w="${W}"${mustUnderstand ? ` ${MU}` : ""}><w:p><w:r><w:t>Header 84</w:t></w:r></w:p></w:hdr>`;
/** `parts` plus word/header83.xml typed header; `relate` adds the main document's relationship, `use` its w:sectPr reference. */
const withHeader = (parts: Parts, header: string | undefined, relate: boolean, use: boolean): Parts => {
    const out: Parts = new Map(parts);
    if (header !== undefined) {
        out.set(
            CT,
            encoder.encode(
                replaceOnce(
                    textOf(parts, CT),
                    "</Types>",
                    `<Override PartName="/word/${UNRELATED}" ContentType="${WML}.header+xml"/></Types>`,
                ),
            ),
        );
        out.set(`word/${UNRELATED}`, encoder.encode(header));
    }
    if (relate)
        out.set(
            MAIN_RELS,
            encoder.encode(
                replaceOnce(
                    textOf(parts, MAIN_RELS),
                    "</Relationships>",
                    `<Relationship Id="rId84" Type="${R}/header" Target="${UNRELATED}"/></Relationships>`,
                ),
            ),
        );
    if (use) {
        const main = textOf(parts, MAIN);
        const at = main.lastIndexOf("<w:sectPr");
        const open = main.indexOf(">", at) + 1;
        if (at < 0 || main[open - 2] === "/") throw new Error("no open w:sectPr");
        out.set(
            MAIN,
            encoder.encode(`${main.slice(0, open)}<w:headerReference xmlns:r="${R}" w:type="default" r:id="rId84"/>${main.slice(open)}`),
        );
    }
    return out;
};
const STRAY_FOO = (mustUnderstand: boolean) =>
    `${XML_DECL}<w:document xmlns:w="${W}"${mustUnderstand ? ` ${MU}` : ""}><w:body/></w:document>`;
const withStrayFoo = (mustUnderstand: boolean): Parts =>
    new Map([...minimal(), ["word/foo.xml", encoder.encode(STRAY_FOO(mustUnderstand))]]);
const mainMustUnderstand = (): Parts => {
    const parts = minimal();
    // The minimal root already binds mc; add the urn:foo binding and the MustUnderstand only.
    parts.set(
        MAIN,
        encoder.encode(
            replaceOnce(textOf(parts, MAIN), / mc:Ignorable="w14">/, ` xmlns:foo="urn:foo" mc:Ignorable="w14" mc:MustUnderstand="foo">`),
        ),
    );
    return parts;
};
const CHOICE_BROKEN = "broken/package.word-choice-requires-undeclared.docx";
const CHOICE_CLEAN = "working/package.word-choice-requires-declared.docx";

type Row = [string, string, () => Promise<Uint8Array>];
const chunks: Record<string, Row[]> = {
    s84a: [
        [
            "mu-unrelated-header",
            "#1116 mce-must-understand: minimal plus word/header83.xml, typed header, named by no relationship, root MustUnderstand urn:foo",
            async () => pack(withHeader(minimal(), headerXml(true), false, false)),
        ],
        [
            "mu-unrelated-header-calibration",
            "calibration: the same header without MustUnderstand",
            async () => pack(withHeader(minimal(), headerXml(false), false, false)),
        ],
        [
            "mu-stray-foo",
            "#1116/#639 mce-must-understand: minimal plus word/foo.xml (no Override, no relationship), w:document root MustUnderstand urn:foo",
            async () => pack(withStrayFoo(true)),
        ],
        ["mu-stray-foo-calibration", "calibration: the same word/foo.xml without MustUnderstand", async () => pack(withStrayFoo(false))],
        [
            "mu-used-header",
            "#1116 mce-must-understand: the header related by the main document and referenced by its w:sectPr",
            async () => pack(withHeader(minimal(), headerXml(true), true, true)),
        ],
        [
            "mu-unused-header",
            "#1116 mce-must-understand: the header related by the main document, referenced by nothing",
            async () => pack(withHeader(minimal(), headerXml(true), true, false)),
        ],
        [
            "mu-main",
            "#1116 mce-must-understand: the main document's root carrying MustUnderstand urn:foo",
            async () => pack(mainMustUnderstand()),
        ],
        [
            "choice-unused-header",
            `#1116 mce-malformed: ${CHOICE_CLEAN} plus word/${UNRELATED} holding ${CHOICE_BROKEN}'s body, related by the main document, referenced by nothing`,
            async () => pack(withHeader(withUnrelatedHeader(await load(CHOICE_CLEAN), await load(CHOICE_BROKEN)), undefined, true, false)),
        ],
        ["s84a-control-minimal", "control", async () => buildDocx({ ...(MINIMAL_PARTS as Record<string, string>) })],
    ],
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-84 chunk: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s84a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s84/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-84 part of docs/plans/evidence/word-probes-2026-10-24.md into s84/section.md.

Reads the chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s84a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s84/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def strict_cell(v):
    # Strict also reports the specimens' unreferenced-part, paraId, content-type and XSD findings; the column names only
    # the markup-compatibility findings, the ones this session probes.
    if v["valid"] is None:
        return cell(v)
    if v["valid"]:
        return "valid"
    mce = [e for e in v["errors"] if e.startswith("mce-")]
    return "invalid: " + (", ".join(f"`{e}`" for e in mce) if mce else "no markup-compatibility finding")


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {strict_cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            record = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                      "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                      "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                      "pdf": row["pdf"], "evidence": row["evidence"]}
            error = manifest(r, s["file"]).get("error")
            if error:
                record["error"] = error
            raw.append(json.dumps(record, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

REFUSED = {"mu-used-header.docx", "mu-main.docx"}
FINDING = {"mu-unrelated-header.docx", "mu-stray-foo.docx", "mu-used-header.docx", "mu-unused-header.docx",
           "mu-main.docx", "choice-unused-header.docx"}
# The narrative's claims, checked against results.json: every row's four readings agree; Word offered to recover the two
# read placements and opened every other row clean; word-valid at the probed revision rejects every row holding a
# finding and passes the rest, so it is wrong exactly on the four clean rows holding one.
for (label, file), r in results.items():
    assert r["agreed"], (label, file, r)
    if file in REFUSED:
        assert r["everyReadingRejects"] and r["outcome"] == "unreadable-content-warning", (label, file, r)
    else:
        assert set(r["readings"]) == {"clean-open"}, (label, file, r)
    assert r["wordValid"] is (file not in FINDING), (label, file, r)
    assert r["validatorMatchesWord"] is (file not in FINDING - REFUSED), (label, file, r)
assert agreed == len(rows) == 9, (agreed, len(rows))
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == files, (run, opened)
# The text Word rendered, both runs: every row it opened on the minimal package renders the main document's "Hello" and
# never the header's "Header 84"; the Choice row renders what its clean twin renders in session 83 (nothing); a refused
# row left no PDF.
texts = {}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
            file = json.loads(line)["original_filename"]
            text = rendered(run, file)
            texts.setdefault(file, set()).add(text)
            if file in REFUSED:
                assert text is None, (run, file, text)
for file, seen in texts.items():
    if file in REFUSED:
        continue
    assert seen == ({""} if file == "choice-unused-header.docx" else {"Hello"}), (file, seen)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
out = [
    f"### Session 84: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Whether Word judges markup compatibility in a `word/` part it does not read "
    "([#1116](https://github.com/jandira-tech/docx-validate/issues/1116)). Session 83 (s83d) opened clean an "
    "undeclared-`Requires` Choice (`mce-malformed`) in a `word/header83.xml` that no relationship names, and refused it "
    "in a main document stored as `word/main.xml`. `mce-must-understand` in such a part was unprobed, and #639's rows "
    "pinned it blocking in a stray `word/foo.xml`. One chunk, s84a, mostly on the minimal package:",
    "",
    "- `mu-unrelated-header` adds `word/header83.xml`, typed header by its Override and named by no relationship, whose "
    "`w:hdr` root carries `mc:MustUnderstand=\"foo\"` for an unknown `urn:foo`; its `-calibration` drops the attribute;",
    "- `mu-stray-foo` is #639's specimen, `word/foo.xml` with no Override and no relationship, a `w:document` root "
    "carrying the same attribute around an empty body, with its `-calibration`;",
    "- `mu-used-header` has the main document relate the header and the body's `w:sectPr` reference it, and "
    "`mu-unused-header` has it related and referenced by nothing;",
    "- `mu-main` puts the attribute on the main document's root;",
    "- `choice-unused-header` is session 83's `choice-requires-undeclared-unrelated-header` with the main document "
    "relating the header and nothing referencing it.",
    "",
    "The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. "
    "Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. Shape is "
    f"the builder's description of the specimen. The builder recorded the validator revision in every row (`{rev}`), "
    "judging an export of that commit. The strict column names only the markup-compatibility findings.",
    "",
    "Every calibration and the control opened clean. Every row Word opened renders the main document's `Hello` in both "
    "runs (`pdftotext`), never the header's `Header 84`; the Choice row renders no text, as its clean twin did in "
    "session 83. No refused row left a PDF.",
    "",
    "- **Word refuses an unknown `mc:MustUnderstand` in a part it reads.** It offered to recover unreadable content for "
    "the main document's root and for a header the body references.",
    "- **It does not judge it in a part no relationship names.** It opened clean the unrelated header and #639's stray "
    "`word/foo.xml`, as it opened session 83's Choice there.",
    "- **Nor in a header the main document relates but does not use.** It opened clean the related, unreferenced header "
    "holding the attribute and the one holding session 83's Choice.",
    "",
    f"Word-valid at {at} matches Word on {matches} of {len(rows)} rows: it rejects the four clean rows that hold a "
    "finding. #1116 makes both findings warn in a `word/` part no relationship names, so it passes `mu-unrelated-header` "
    "and `mu-stray-foo`; [#1125](https://github.com/jandira-tech/docx-validate/issues/1125) covers the two related, "
    "unused headers.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 84</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 84 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. "
    "The builder ran on an export of the recorded revision (`git archive`), `node_modules` linked in, with `WT` and "
    "`REVISION` naming them.",
    "",
]
for name, path, lang in (("s84builder.mts", ROOT / "s84builder.mts", "ts"), ("compare.py", ROOT / "s84/compare.py", "python"),
                         ("section.py", ROOT / "s84/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s84/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 85: 16:51Z–17:16Z on 2026-10-28, validator columns at 57e150ae

Three open questions, on the minimal package. Five chunks; s85e was added after s85c's first run.

- **s85a and s85b, [#1145](https://github.com/jandira-tech/docx-validate/issues/1145).** Does Word read a footnotes, endnotes or comments part the main document relates when the part's only reference sits in a used header? Each part's root carries `mc:MustUnderstand="foo"` for an unknown `urn:foo`, which Word refused on the main document's root and in a used header (session 84). Per kind: `-mu-header-reference` has a read header (`word/header1.xml`, referenced by the section) hold the part's only reference; `-mu-body-reference` references the same part from the body; `-header-reference-calibration` is the header-referenced part without the attribute; `-mu-unreferenced` relates the part and references it nowhere. s85b adds a footer holding the attribute, related and unused (`footer-mu-unused`) or referenced by the section (`footer-mu-used`).
- **s85c and s85e, [#1127](https://github.com/jandira-tech/docx-validate/issues/1127).** Does Word read a part an internal target names through a scheme-like spelling? s85c relates a used header through `Target="ftp:header1.xml"` or `"httpfoo:header1.xml"`, stored as `word/ftp:header1.xml` or `word/httpfoo:header1.xml`, and the styles part through `ftp:styles.xml`, each with an unclosed root and `-wellformed`; the plain-name twins of the unclosed header and styles part are calibrations. s85e separates the stored name from the target: `colon-part-unrelated` stores a well-formed `word/ftp:header1.xml`, typed header and named by no relationship, and `colon-part-default-type` the same part with no Override; `ftp-target-plain-part` and `httpfoo-target-plain-part` relate a used header through the scheme-like target while the part is stored as plain `word/header1.xml`; `header-dotslash-ftp-wellformed` uses the stored `word/ftp:header1.xml` through `Target="./ftp:header1.xml"`, which names it without a scheme.
- **s85d, [#1136](https://github.com/jandira-tech/docx-validate/issues/1136).** Does an unclosed relationships part Word never reads matter? Session 84's `mu-stray-foo` plus an unclosed `word/_rels/stray.xml.rels` with no source part, or plus a stray `word/x.xml` with an unclosed `word/_rels/x.xml.rels`; each broken sidecar alone; and `mu-stray-foo` again.

Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 37 of 37 rows agree. The two times in Observed are the ends of the first and second runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc`). The strict column names the markup-compatibility, XML-syntax and relationship findings, and counts the others.

Every calibration Word was meant to open, and every control, opened clean. Every row Word opened renders the main document's `Hello` in both runs (`pdftotext`), after the header's `Header 85` where the section references a header, and never a note's or comment's `Text 85`. No refused row left a PDF.

- **Word does not read a notes or comments part whose only reference is in a header.** It opened clean all three `-mu-header-reference` rows, and offered to recover unreadable content for the same parts referenced from the body. It opened clean the related, unreferenced part of each kind and the unused footer, and refused the used footer.
- **Word refuses a stored part name holding a colon, read or not.** It offered recovery for `word/ftp:header1.xml` named by no relationship, with or without its Override, and for every scheme-like s85c row, well-formed or not. The unclosed plain-name header drew an open error and the unclosed plain styles part a recovery offer.
- **It refuses a used header whose target spells a scheme, too.** With the part stored as plain `word/header1.xml` and no colon in any stored name, `Target="ftp:header1.xml"` and `"httpfoo:header1.xml"` drew the recovery offer. These rows do not show whether Word reads the target as a missing part or refuses the spelling.
- **A broken relationships part Word never reads does not matter.** It opened clean every s85d row, `mu-stray-foo` beside either broken sidecar included.

Word-valid at 57e150ae matches Word on 21 of 37 rows. It rejects the three header-only rows Word opened clean ([#1145](https://github.com/jandira-tech/docx-validate/issues/1145)'s conservative half, narrowed back by [#1155](https://github.com/jandira-tech/docx-validate/issues/1155)) and the two `mu-stray-foo` rows beside a broken sidecar ([#1136](https://github.com/jandira-tech/docx-validate/issues/1136)). It passes the eleven scheme-like and colon rows Word refused.

| Run    | Observed             | Specimen                                 | Shape                                                                                                                    | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 57e150ae                            | strict at 57e150ae                                                                                                                                                                              |
| ------ | -------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s85a` | 16:51:31Z, 16:52:20Z | `footnotes-mu-header-reference`          | #1145: word/footnotes.xml related by the main document, root MustUnderstand urn:foo, its only reference in a read header | `67420c3fd6920f0b` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/footnotes.xml` | invalid: `mce-must-understand@word/footnotes.xml`, 2 other findings                                                                                                                             |
| `s85a` | 16:51:31Z, 16:52:20Z | `footnotes-mu-body-reference`            | #1145 calibration: the same part referenced from the body                                                                | `11dfe31d37f8a6d4` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/footnotes.xml` | invalid: `mce-must-understand@word/footnotes.xml`, 1 other finding                                                                                                                              |
| `s85a` | 16:51:31Z, 16:52:20Z | `footnotes-header-reference-calibration` | calibration: the header-referenced part without MustUnderstand                                                           | `5ae261d3ccfb786f` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: 2 other findings                                                                                                                                                                       |
| `s85a` | 16:51:31Z, 16:52:20Z | `footnotes-mu-unreferenced`              | #1146: the MustUnderstand part related by the main document, referenced by nothing                                       | `78c8433199f153c3` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `mce-must-understand@word/footnotes.xml`, 1 other finding                                                                                                                              |
| `s85a` | 16:51:31Z, 16:52:20Z | `endnotes-mu-header-reference`           | #1145: word/endnotes.xml related by the main document, root MustUnderstand urn:foo, its only reference in a read header  | `2a8ad97eb4770feb` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/endnotes.xml`  | invalid: `mce-must-understand@word/endnotes.xml`, 2 other findings                                                                                                                              |
| `s85a` | 16:51:31Z, 16:52:20Z | `endnotes-mu-body-reference`             | #1145 calibration: the same part referenced from the body                                                                | `fac2296887824d3d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/endnotes.xml`  | invalid: `mce-must-understand@word/endnotes.xml`, 1 other finding                                                                                                                               |
| `s85a` | 16:51:31Z, 16:52:20Z | `endnotes-header-reference-calibration`  | calibration: the header-referenced part without MustUnderstand                                                           | `323f6068ad224f71` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: 2 other findings                                                                                                                                                                       |
| `s85a` | 16:51:31Z, 16:52:20Z | `endnotes-mu-unreferenced`               | #1146: the MustUnderstand part related by the main document, referenced by nothing                                       | `77f933ee603b2ebd` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `mce-must-understand@word/endnotes.xml`, 1 other finding                                                                                                                               |
| `s85a` | 16:51:31Z, 16:52:20Z | `s85a-control-minimal`                   | control                                                                                                                  | `61bfad1e57ed38b4` | clean-open     | clean-open     | clean-open                 | valid                                             | valid                                                                                                                                                                                           |
| `s85b` | 16:52:59Z, 16:53:39Z | `comments-mu-header-reference`           | #1145: word/comments.xml related by the main document, root MustUnderstand urn:foo, its only reference in a read header  | `30e2e39ba5012b9f` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/comments.xml`  | invalid: `mce-must-understand@word/comments.xml`, 3 other findings                                                                                                                              |
| `s85b` | 16:52:59Z, 16:53:39Z | `comments-mu-body-reference`             | #1145 calibration: the same part referenced from the body                                                                | `4962384abe66827b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/comments.xml`  | invalid: `mce-must-understand@word/comments.xml`, 2 other findings                                                                                                                              |
| `s85b` | 16:52:59Z, 16:53:39Z | `comments-header-reference-calibration`  | calibration: the header-referenced part without MustUnderstand                                                           | `8f0a9bc031dd949a` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: 3 other findings                                                                                                                                                                       |
| `s85b` | 16:52:59Z, 16:53:39Z | `comments-mu-unreferenced`               | #1146: the MustUnderstand part related by the main document, referenced by nothing                                       | `c80dd21027417896` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `mce-must-understand@word/comments.xml`, 2 other findings                                                                                                                              |
| `s85b` | 16:52:59Z, 16:53:39Z | `footer-mu-unused`                       | #1146: word/footer1.xml related by the main document, referenced by nothing, root MustUnderstand urn:foo                 | `5779f234c076f6be` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `mce-must-understand@word/footer1.xml`, 1 other finding                                                                                                                                |
| `s85b` | 16:52:59Z, 16:53:39Z | `footer-mu-used`                         | calibration: the same footer referenced by the section                                                                   | `9038370cc28717ca` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/footer1.xml`   | invalid: `mce-must-understand@word/footer1.xml`, 1 other finding                                                                                                                                |
| `s85b` | 16:52:59Z, 16:53:39Z | `s85b-control-minimal`                   | control                                                                                                                  | `eee41e1d0a860fea` | clean-open     | clean-open     | clean-open                 | valid                                             | valid                                                                                                                                                                                           |
| `s85c` | 17:04:35Z, 17:09:42Z | `header-ftp-unclosed`                    | #1127: a used header related by Target="ftp:header1.xml", stored as word/ftp:header1.xml with an unclosed root           | `c9fa87ee2373619c` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `xml-syntax@word/ftp:header1.xml`                                                                                                                                                      |
| `s85c` | 17:04:35Z, 17:09:42Z | `header-ftp-wellformed`                  | #1127 twin: the same header closed                                                                                       | `86258800626d31e5` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | valid                                                                                                                                                                                           |
| `s85c` | 17:04:35Z, 17:09:42Z | `header-httpfoo-unclosed`                | #1127: a used header related by Target="httpfoo:header1.xml", stored as word/httpfoo:header1.xml with an unclosed root   | `f31c7e7953d45ffd` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `xml-syntax@word/httpfoo:header1.xml`                                                                                                                                                  |
| `s85c` | 17:04:35Z, 17:09:42Z | `header-httpfoo-wellformed`              | #1127 twin: the same header closed                                                                                       | `6438740efba2aae1` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | valid                                                                                                                                                                                           |
| `s85c` | 17:04:35Z, 17:09:42Z | `styles-ftp-unclosed`                    | #1127: the styles relationship's Target "ftp:styles.xml", the part stored as word/ftp:styles.xml with an unclosed root   | `1310e3f1f6609c8a` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `xml-syntax@word/ftp:styles.xml`                                                                                                                                                       |
| `s85c` | 17:04:35Z, 17:09:42Z | `styles-ftp-wellformed`                  | #1127 twin: the same styles part closed                                                                                  | `22bed2cfba597270` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | valid                                                                                                                                                                                           |
| `s85c` | 17:04:35Z, 17:09:42Z | `header-plain-unclosed`                  | calibration: the unclosed used header related by Target="header1.xml"                                                    | `a07069879e12d974` | open-error     | open-error     | open-error                 | invalid: `xml-syntax@word/header1.xml`            | invalid: `xml-syntax@word/header1.xml`                                                                                                                                                          |
| `s85c` | 17:04:35Z, 17:09:42Z | `styles-plain-unclosed`                  | calibration: the minimal word/styles.xml with an unclosed root                                                           | `e10ed7cadf5e08ea` | repair-warning | repair-warning | unreadable-content-warning | invalid: `xml-syntax@word/styles.xml`             | invalid: `xml-syntax@word/styles.xml`                                                                                                                                                           |
| `s85c` | 17:04:35Z, 17:09:42Z | `s85c-control-minimal`                   | control                                                                                                                  | `eee41e1d0a860fea` | clean-open     | clean-open     | clean-open                 | valid                                             | valid                                                                                                                                                                                           |
| `s85d` | 17:05:26Z, 17:05:47Z | `mu-stray-foo-broken-stray-sidecar`      | #1136: s84a's mu-stray-foo plus an unclosed word/_rels/stray.xml.rels with no word/stray.xml                             | `5b3c2e719db53050` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/foo.xml`       | invalid: `xml-syntax@word/_rels/stray.xml.rels`, `rels-unreferenced@word/foo.xml`, `mce-must-understand@word/foo.xml`, 1 other finding                                                          |
| `s85d` | 17:05:26Z, 17:05:47Z | `mu-stray-foo-broken-x-sidecar`          | #1136: s84a's mu-stray-foo plus word/x.xml (no Override, no relationship) and an unclosed word/_rels/x.xml.rels          | `374a7063dafd63b2` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/foo.xml`       | invalid: `xml-syntax@word/_rels/x.xml.rels`, `rels-unreferenced@word/foo.xml`, `rels-unreferenced@word/x.xml`, `rels-id-parse@word/x.xml`, `mce-must-understand@word/foo.xml`, 2 other findings |
| `s85d` | 17:05:26Z, 17:05:47Z | `mu-stray-foo`                           | #1136 calibration: s84a's mu-stray-foo repeated                                                                          | `6fb510129c390be0` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `rels-unreferenced@word/foo.xml`, `mce-must-understand@word/foo.xml`, 1 other finding                                                                                                  |
| `s85d` | 17:05:26Z, 17:05:47Z | `broken-stray-sidecar-only`              | #1136 calibration: the unclosed word/_rels/stray.xml.rels alone                                                          | `3d67e43eb61f87cb` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `xml-syntax@word/_rels/stray.xml.rels`                                                                                                                                                 |
| `s85d` | 17:05:26Z, 17:05:47Z | `broken-x-sidecar-only`                  | #1136 calibration: word/x.xml with its unclosed sidecar alone                                                            | `82ece1e6cdd01451` | clean-open     | clean-open     | clean-open                 | valid                                             | invalid: `xml-syntax@word/_rels/x.xml.rels`, `rels-unreferenced@word/x.xml`, `rels-id-parse@word/x.xml`, 1 other finding                                                                        |
| `s85d` | 17:05:26Z, 17:05:47Z | `s85d-control-minimal`                   | control                                                                                                                  | `5fcd2e7b39cc4da9` | clean-open     | clean-open     | clean-open                 | valid                                             | valid                                                                                                                                                                                           |
| `s85e` | 17:12:25Z, 17:16:09Z | `colon-part-unrelated`                   | #1127 follow-up: minimal plus a well-formed word/ftp:header1.xml, typed header, named by no relationship                 | `50b91dc4c90153e7` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `rels-unreferenced@word/ftp:header1.xml`                                                                                                                                               |
| `s85e` | 17:12:25Z, 17:16:09Z | `colon-part-default-type`                | #1127 follow-up: the same part with no Override                                                                          | `ba2ec5f0a4396f6f` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `rels-unreferenced@word/ftp:header1.xml`                                                                                                                                               |
| `s85e` | 17:12:25Z, 17:16:09Z | `ftp-target-plain-part`                  | #1127 follow-up: a used header related by Target="ftp:header1.xml", stored as word/header1.xml                           | `411a7868d38f110d` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/header1.xml`, 1 other finding                                                                                      |
| `s85e` | 17:12:25Z, 17:16:09Z | `httpfoo-target-plain-part`              | #1127 follow-up: a used header related by Target="httpfoo:header1.xml", stored as word/header1.xml                       | `5c9885613d76b61f` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/header1.xml`, 1 other finding                                                                                      |
| `s85e` | 17:12:25Z, 17:16:09Z | `header-dotslash-ftp-wellformed`         | #1127 follow-up: the well-formed word/ftp:header1.xml used through Target="./ftp:header1.xml"                            | `f201015f873e39db` | repair-warning | repair-warning | unreadable-content-warning | valid                                             | valid                                                                                                                                                                                           |
| `s85e` | 17:12:25Z, 17:16:09Z | `s85e-control-minimal`                   | control                                                                                                                  | `db2bec53e98f4253` | clean-open     | clean-open     | clean-open                 | valid                                             | valid                                                                                                                                                                                           |

<details><summary>Raw records, session 85</summary>

```jsonl
{"run": "s85a", "pass": 1, "name": "footnotes-mu-header-reference", "sha256": "67420c3fd6920f0bac68cdc95b4db737dc753e5212b808160c5bc264952083f8", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00006__wfv__footnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "footnotes-mu-header-reference", "sha256": "67420c3fd6920f0bac68cdc95b4db737dc753e5212b808160c5bc264952083f8", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00006__wfv__footnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "footnotes-mu-body-reference", "sha256": "11dfe31d37f8a6d47a4aef00f8f8a77d08983ad3051408714f4219a810a5ab61", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00005__wfv__footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:51:26.781 'Word found unreadable content in 00005__wfv__footnotes-mu-body-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:51:27.564 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__footnotes-mu-body-referen...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85a", "pass": 2, "name": "footnotes-mu-body-reference", "sha256": "11dfe31d37f8a6d47a4aef00f8f8a77d08983ad3051408714f4219a810a5ab61", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00005__wfv__footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:52:18.121 'Word found unreadable content in 00005__wfv__footnotes-mu-body-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.'"], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__footnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s85a", "pass": 1, "name": "footnotes-header-reference-calibration", "sha256": "5ae261d3ccfb786f8046c90a2271628531c5d9db208ae7e1eda33efccd50e979", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00004__wfv__footnotes-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "footnotes-header-reference-calibration", "sha256": "5ae261d3ccfb786f8046c90a2271628531c5d9db208ae7e1eda33efccd50e979", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00004__wfv__footnotes-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "footnotes-mu-unreferenced", "sha256": "78c8433199f153c3dec698cc3acfbf67b7869df00d4cf9400b6a0bb6570e47bf", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00007__wfv__footnotes-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "footnotes-mu-unreferenced", "sha256": "78c8433199f153c3dec698cc3acfbf67b7869df00d4cf9400b6a0bb6570e47bf", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00007__wfv__footnotes-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "endnotes-mu-header-reference", "sha256": "2a8ad97eb4770feb96764a12c5c74f0d338900dba7aa265096d2df2171d7c9a5", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00002__wfv__endnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "endnotes-mu-header-reference", "sha256": "2a8ad97eb4770feb96764a12c5c74f0d338900dba7aa265096d2df2171d7c9a5", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00002__wfv__endnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "endnotes-mu-body-reference", "sha256": "fac2296887824d3def5b119b00d55e915ba273f07ea716a8697f77e173733e7f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00001__wfv__endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:50:22.703 \"Word found unreadable content in 00001__wfv__endnotes-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\"", "2026-10-28 12:50:22.704 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__endnotes-mu-body-referenc...)\""], "error": "Microsoft Word got an error: AppleEvent timed out."}
{"run": "s85a", "pass": 2, "name": "endnotes-mu-body-reference", "sha256": "fac2296887824d3def5b119b00d55e915ba273f07ea716a8697f77e173733e7f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00001__wfv__endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:51:57.279 'Word found unreadable content in 00001__wfv__endnotes-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:51:58.157 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__endnotes-mu-body-referenc...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__endnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s85a", "pass": 1, "name": "endnotes-header-reference-calibration", "sha256": "323f6068ad224f71e2d5d5396e4c2c88a39cc18a32ef8c8b260d294476436f52", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00000__wfv__endnotes-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "endnotes-header-reference-calibration", "sha256": "323f6068ad224f71e2d5d5396e4c2c88a39cc18a32ef8c8b260d294476436f52", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00000__wfv__endnotes-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "endnotes-mu-unreferenced", "sha256": "77f933ee603b2ebd78f91a95e1943137b824820792314dd029d607f28c2519b0", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00003__wfv__endnotes-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "endnotes-mu-unreferenced", "sha256": "77f933ee603b2ebd78f91a95e1943137b824820792314dd029d607f28c2519b0", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00003__wfv__endnotes-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 1, "name": "s85a-control-minimal", "sha256": "61bfad1e57ed38b44a133dda758c1d48f0d33fa6093ba7f1cc2aaab8aed5f38a", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:51:31+00:00", "staged": "00008__wfv__s85a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85a", "pass": 2, "name": "s85a-control-minimal", "sha256": "61bfad1e57ed38b44a133dda758c1d48f0d33fa6093ba7f1cc2aaab8aed5f38a", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:20+00:00", "staged": "00008__wfv__s85a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 1, "name": "comments-mu-header-reference", "sha256": "30e2e39ba5012b9f6683404195a89d5aafc0dbe3f08451ad6e859c8fa56bfc5c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00002__wfv__comments-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 2, "name": "comments-mu-header-reference", "sha256": "30e2e39ba5012b9f6683404195a89d5aafc0dbe3f08451ad6e859c8fa56bfc5c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00002__wfv__comments-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-header-reference_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 1, "name": "comments-mu-body-reference", "sha256": "4962384abe66827b849678aac515d5df1a7c0589273e034579c43cf22fb3c5f1", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00001__wfv__comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:52:41.398 'Word found unreadable content in 00001__wfv__comments-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:52:42.243 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-mu-body-referenc...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__comments-mu-body-reference.docx; refusing to guess"}
{"run": "s85b", "pass": 2, "name": "comments-mu-body-reference", "sha256": "4962384abe66827b849678aac515d5df1a7c0589273e034579c43cf22fb3c5f1", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00001__wfv__comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:53:19.538 'Word found unreadable content in 00001__wfv__comments-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:53:20.375 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__comments-mu-body-referenc...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__comments-mu-body-reference.docx; refusing to guess"}
{"run": "s85b", "pass": 1, "name": "comments-header-reference-calibration", "sha256": "8f0a9bc031dd949aeced5b1f4a4a17c3e8c026e9ba7ffb5efefeb3a177f8b769", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00000__wfv__comments-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 2, "name": "comments-header-reference-calibration", "sha256": "8f0a9bc031dd949aeced5b1f4a4a17c3e8c026e9ba7ffb5efefeb3a177f8b769", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00000__wfv__comments-header-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-header-reference-calibration_byword.pdf (16228 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 1, "name": "comments-mu-unreferenced", "sha256": "c80dd210274178968185c424304806f465d67206b13c51cc49b4c5e73290975b", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00003__wfv__comments-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 2, "name": "comments-mu-unreferenced", "sha256": "c80dd210274178968185c424304806f465d67206b13c51cc49b4c5e73290975b", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00003__wfv__comments-mu-unreferenced.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-unreferenced_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 1, "name": "footer-mu-unused", "sha256": "5779f234c076f6be678b6f4685ed1c90fbf9583590c31b4a1a8f71369e40b991", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00004__wfv__footer-mu-unused.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-mu-unused_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 2, "name": "footer-mu-unused", "sha256": "5779f234c076f6be678b6f4685ed1c90fbf9583590c31b4a1a8f71369e40b991", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00004__wfv__footer-mu-unused.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-mu-unused_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 1, "name": "footer-mu-used", "sha256": "9038370cc28717cac08a5810578866d8f578de4509270b8b6f9ec89fae32a69f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00005__wfv__footer-mu-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:52:59.270 \"Word found unreadable content in 00005__wfv__footer-mu-used.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__footer-mu-used.docx; refusing to guess"}
{"run": "s85b", "pass": 2, "name": "footer-mu-used", "sha256": "9038370cc28717cac08a5810578866d8f578de4509270b8b6f9ec89fae32a69f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00005__wfv__footer-mu-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:53:38.737 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … Recovery converter.\\n(00005__wfv__footer-mu-used.docx)'", "2026-10-28 12:53:38.976 \"Word found unreadable content in 00005__wfv__footer-mu-used.docx. Do you want to recover the conten … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__footer-mu-used.docx; refusing to guess"}
{"run": "s85b", "pass": 1, "name": "s85b-control-minimal", "sha256": "eee41e1d0a860fead6fe60b68ab01d8e4e5b5ed122538eaf697d20c93fee2a2c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:52:59+00:00", "staged": "00006__wfv__s85b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85b", "pass": 2, "name": "s85b-control-minimal", "sha256": "eee41e1d0a860fead6fe60b68ab01d8e4e5b5ed122538eaf697d20c93fee2a2c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T16:53:39+00:00", "staged": "00006__wfv__s85b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85c", "pass": 1, "name": "header-ftp-unclosed", "sha256": "c9fa87ee2373619c753a34dd32c039eac7268532d891c295c1a046f247627af3", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00000__wfv__header-ftp-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:54:00.098 'Word found unreadable content in 00000__wfv__header-ftp-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:54:00.887 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00000__wfv__header-ftp-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__header-ftp-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "header-ftp-unclosed", "sha256": "c9fa87ee2373619c753a34dd32c039eac7268532d891c295c1a046f247627af3", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00000__wfv__header-ftp-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:06:40.829 'Word found unreadable content in 00000__wfv__header-ftp-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:06:47.362 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00000__wfv__header-ftp-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__header-ftp-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 1, "name": "header-ftp-wellformed", "sha256": "86258800626d31e56a22454d59f23696e160c086df9dea137930ac6a38ca6c92", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00001__wfv__header-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:54:53.551 Microsoft Word, Word found unreadable content in 00001__wfv__header-ftp-wellformed.docx. Do you want … t? If you trust the source of this document, click Yes.", "2026-10-28 12:55:00.056 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00001__wfv__header-ftp-wellformed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__header-ftp-wellformed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "header-ftp-wellformed", "sha256": "86258800626d31e56a22454d59f23696e160c086df9dea137930ac6a38ca6c92", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00001__wfv__header-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:07:44.087 Microsoft Word, Word found unreadable content in 00001__wfv__header-ftp-wellformed.docx. Do you want … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__header-ftp-wellformed.docx; refusing to guess"}
{"run": "s85c", "pass": 1, "name": "header-httpfoo-unclosed", "sha256": "f31c7e7953d45ffd28be3a0a4dc3570cbe3fb3a379a283b4b5a0829a8eed7a37", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00002__wfv__header-httpfoo-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:55:55.276 Microsoft Word, Word found unreadable content in 00002__wfv__header-httpfoo-unclosed.docx. Do you wa … t? If you trust the source of this document, click Yes.", "2026-10-28 12:56:11.061 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__header-httpfoo-unclosed.docx)\""], "error": "Microsoft Word got an error: AppleEvent timed out."}
{"run": "s85c", "pass": 2, "name": "header-httpfoo-unclosed", "sha256": "f31c7e7953d45ffd28be3a0a4dc3570cbe3fb3a379a283b4b5a0829a8eed7a37", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00002__wfv__header-httpfoo-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:08:36.267 Microsoft Word, Word found unreadable content in 00002__wfv__header-httpfoo-unclosed.docx. Do you wa … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 1, "name": "header-httpfoo-wellformed", "sha256": "6438740efba2aae10eed004b3bea1f97d48eaceae1c34df5f446e5f8fadc0796", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00003__wfv__header-httpfoo-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:56:23.948 'Word found unreadable content in 00003__wfv__header-httpfoo-wellformed.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:56:32.925 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-httpfoo-wellformed...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__header-httpfoo-wellformed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "header-httpfoo-wellformed", "sha256": "6438740efba2aae10eed004b3bea1f97d48eaceae1c34df5f446e5f8fadc0796", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00003__wfv__header-httpfoo-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:08:41.174 'Word found unreadable content in 00003__wfv__header-httpfoo-wellformed.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:08:47.630 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-httpfoo-wellformed...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 1, "name": "styles-ftp-unclosed", "sha256": "1310e3f1f6609c8a36f6b281c06ef5a2ee9374505bd7d2791c7db8d49a0b31ef", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00006__wfv__styles-ftp-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:58:19.874 \"Word found unreadable content in 00006__wfv__styles-ftp-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__styles-ftp-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "styles-ftp-unclosed", "sha256": "1310e3f1f6609c8a36f6b281c06ef5a2ee9374505bd7d2791c7db8d49a0b31ef", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00006__wfv__styles-ftp-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:09:00.635 'Word found unreadable content in 00006__wfv__styles-ftp-unclosed.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:09:06.646 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00006__wfv__styles-ftp-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 1, "name": "styles-ftp-wellformed", "sha256": "22bed2cfba5972701792cf26fe3b8db92404dbc71c2a49372345bf60b043343f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00007__wfv__styles-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:59:14.009 \"Word found unreadable content in 00007__wfv__styles-ftp-wellformed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 2, "name": "styles-ftp-wellformed", "sha256": "22bed2cfba5972701792cf26fe3b8db92404dbc71c2a49372345bf60b043343f", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00007__wfv__styles-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:09:11.931 'Word found unreadable content in 00007__wfv__styles-ftp-wellformed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:09:18.915 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00007__wfv__styles-ftp-wellformed.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 1, "name": "header-plain-unclosed", "sha256": "a07069879e12d974341fad520a55ac9e29df710dc99ec1022db05cd30a38fa93", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00004__wfv__header-plain-unclosed.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 12:57:25.355 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … ery converter. (00004__wfv__header-plain-unclosed.docx)"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__header-plain-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "header-plain-unclosed", "sha256": "a07069879e12d974341fad520a55ac9e29df710dc99ec1022db05cd30a38fa93", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00004__wfv__header-plain-unclosed.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-28 13:08:54.641 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … y converter.\\n(00004__wfv__header-plain-unclosed.docx)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__header-plain-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 1, "name": "styles-plain-unclosed", "sha256": "e10ed7cadf5e08ea4d4cecd6c520abaca939db346d82b3af3a40dae7ab5f7f4d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00008__wfv__styles-plain-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 12:59:21.062 'Word found unreadable content in 00008__wfv__styles-plain-unclosed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-28 12:59:31.084 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00008__wfv__styles-plain-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00008__wfv__styles-plain-unclosed.docx; refusing to guess"}
{"run": "s85c", "pass": 2, "name": "styles-plain-unclosed", "sha256": "e10ed7cadf5e08ea4d4cecd6c520abaca939db346d82b3af3a40dae7ab5f7f4d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00008__wfv__styles-plain-unclosed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:09:24.152 'Word found unreadable content in 00008__wfv__styles-plain-unclosed.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:09:30.013 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00008__wfv__styles-plain-unclosed.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85c", "pass": 1, "name": "s85c-control-minimal", "sha256": "eee41e1d0a860fead6fe60b68ab01d8e4e5b5ed122538eaf697d20c93fee2a2c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:04:35+00:00", "staged": "00005__wfv__s85c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85c", "pass": 2, "name": "s85c-control-minimal", "sha256": "eee41e1d0a860fead6fe60b68ab01d8e4e5b5ed122538eaf697d20c93fee2a2c", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:09:42+00:00", "staged": "00005__wfv__s85c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "mu-stray-foo-broken-stray-sidecar", "sha256": "5b3c2e719db530506c4a4405adf9ac439c701adfc0d8101141d1344d54124559", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00002__wfv__mu-stray-foo-broken-stray-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-stray-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "mu-stray-foo-broken-stray-sidecar", "sha256": "5b3c2e719db530506c4a4405adf9ac439c701adfc0d8101141d1344d54124559", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00002__wfv__mu-stray-foo-broken-stray-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-stray-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "mu-stray-foo-broken-x-sidecar", "sha256": "374a7063dafd63b20e624d7e71f622cecdd0a321f75f24935dddc76ce28d8c4d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00003__wfv__mu-stray-foo-broken-x-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-x-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "mu-stray-foo-broken-x-sidecar", "sha256": "374a7063dafd63b20e624d7e71f622cecdd0a321f75f24935dddc76ce28d8c4d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00003__wfv__mu-stray-foo-broken-x-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-x-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "mu-stray-foo", "sha256": "6fb510129c390be05e51597507d85f09a8561d7e090af6ce3960fc8a667682bf", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00004__wfv__mu-stray-foo.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "mu-stray-foo", "sha256": "6fb510129c390be05e51597507d85f09a8561d7e090af6ce3960fc8a667682bf", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00004__wfv__mu-stray-foo.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "broken-stray-sidecar-only", "sha256": "3d67e43eb61f87cbad4b9ae6bdf219cb6948d4e181f0743cb02788674057cebd", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00000__wfv__broken-stray-sidecar-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-stray-sidecar-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "broken-stray-sidecar-only", "sha256": "3d67e43eb61f87cbad4b9ae6bdf219cb6948d4e181f0743cb02788674057cebd", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00000__wfv__broken-stray-sidecar-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-stray-sidecar-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "broken-x-sidecar-only", "sha256": "82ece1e6cdd01451a46db340f97bb588e3ff29acfb8d36fed1c20b438ddeb58d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00001__wfv__broken-x-sidecar-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-x-sidecar-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "broken-x-sidecar-only", "sha256": "82ece1e6cdd01451a46db340f97bb588e3ff29acfb8d36fed1c20b438ddeb58d", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00001__wfv__broken-x-sidecar-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-x-sidecar-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 1, "name": "s85d-control-minimal", "sha256": "5fcd2e7b39cc4da986cfc8adcf8d1262442275e3933948ac4dbc7c2ca475c879", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:26+00:00", "staged": "00005__wfv__s85d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85d", "pass": 2, "name": "s85d-control-minimal", "sha256": "5fcd2e7b39cc4da986cfc8adcf8d1262442275e3933948ac4dbc7c2ca475c879", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:05:47+00:00", "staged": "00005__wfv__s85d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85e", "pass": 1, "name": "colon-part-unrelated", "sha256": "50b91dc4c90153e7a1137d15ee72add756c550c8b6ba7096aee2d5f9c77b0b20", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00001__wfv__colon-part-unrelated.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:11:02.093 Microsoft Word, Word found unreadable content in 00001__wfv__colon-part-unrelated.docx. Do you want  … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__colon-part-unrelated.docx; refusing to guess"}
{"run": "s85e", "pass": 2, "name": "colon-part-unrelated", "sha256": "50b91dc4c90153e7a1137d15ee72add756c550c8b6ba7096aee2d5f9c77b0b20", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00001__wfv__colon-part-unrelated.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:13:54.064 \"Word found unreadable content in 00001__wfv__colon-part-unrelated.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__colon-part-unrelated.docx; refusing to guess"}
{"run": "s85e", "pass": 1, "name": "colon-part-default-type", "sha256": "ba2ec5f0a4396f6f09d243e7b575de55829afec02e10ee7df4d3de9a0d4d0241", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00000__wfv__colon-part-default-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:10:04.496 'Word found unreadable content in 00000__wfv__colon-part-default-type.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:10:10.310 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__colon-part-default-type.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__colon-part-default-type.docx; refusing to guess"}
{"run": "s85e", "pass": 2, "name": "colon-part-default-type", "sha256": "ba2ec5f0a4396f6f09d243e7b575de55829afec02e10ee7df4d3de9a0d4d0241", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00000__wfv__colon-part-default-type.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:12:54.945 'Word found unreadable content in 00000__wfv__colon-part-default-type.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:13:00.976 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__colon-part-default-type.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__colon-part-default-type.docx; refusing to guess"}
{"run": "s85e", "pass": 1, "name": "ftp-target-plain-part", "sha256": "411a7868d38f110d0cee593194d4b65b96ca5a48b66816e9a775cd79c94551d4", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00002__wfv__ftp-target-plain-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:12:00.770 \"Word found unreadable content in 00002__wfv__ftp-target-plain-part.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85e", "pass": 2, "name": "ftp-target-plain-part", "sha256": "411a7868d38f110d0cee593194d4b65b96ca5a48b66816e9a775cd79c94551d4", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00002__wfv__ftp-target-plain-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:14:43.179 'Word found unreadable content in 00002__wfv__ftp-target-plain-part.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:16:09.446 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__ftp-target-plain-part.docx)\""], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00002__wfv__ftp-target-plain-part.docx; refusing to guess"}
{"run": "s85e", "pass": 1, "name": "httpfoo-target-plain-part", "sha256": "5c9885613d76b61fef0f42dafb5ab941f5439b1dbca8fb2907c0fd9ec91c9a07", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00004__wfv__httpfoo-target-plain-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:12:16.617 'Word found unreadable content in 00004__wfv__httpfoo-target-plain-part.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:12:23.815 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__httpfoo-target-plain-part...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85e", "pass": 2, "name": "httpfoo-target-plain-part", "sha256": "5c9885613d76b61fef0f42dafb5ab941f5439b1dbca8fb2907c0fd9ec91c9a07", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00004__wfv__httpfoo-target-plain-part.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:16:01.390 Microsoft Word, Word found unreadable content in 00004__wfv__httpfoo-target-plain-part.docx. Do you  … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__httpfoo-target-plain-part.docx; refusing to guess"}
{"run": "s85e", "pass": 1, "name": "header-dotslash-ftp-wellformed", "sha256": "f201015f873e39dbb6d94254d5d43335729f1ac1ca1298902cbd7946863386c7", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00003__wfv__header-dotslash-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:12:05.359 'Word found unreadable content in 00003__wfv__header-dotslash-ftp-wellformed.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:12:11.062 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-dotslash-ftp-wellf...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85e", "pass": 2, "name": "header-dotslash-ftp-wellformed", "sha256": "f201015f873e39dbb6d94254d5d43335729f1ac1ca1298902cbd7946863386c7", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00003__wfv__header-dotslash-ftp-wellformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 13:15:06.449 'Word found unreadable content in 00003__wfv__header-dotslash-ftp-wellformed.docx. Do you want to re … ? If you trust the source of this document, click Yes.'", "2026-10-28 13:15:12.300 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-dotslash-ftp-wellf...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s85e", "pass": 1, "name": "s85e-control-minimal", "sha256": "db2bec53e98f425305a8f559cd573cc4bc1464b1e459bcc7c704d6736ebd87c1", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:12:25+00:00", "staged": "00005__wfv__s85e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s85e", "pass": 2, "name": "s85e-control-minimal", "sha256": "db2bec53e98f425305a8f559cd573cc4bc1464b1e459bcc7c704d6736ebd87c1", "validatorRevision": "57e150ae2ed41cec22d1b8b6b8888fff39e6ffbc", "observedAt": "2026-10-28T17:16:09+00:00", "staged": "00005__wfv__s85e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s85e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 85 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. The builder ran in the committed worktree, `WT` naming it. s85c's first run outlasted the 10-minute foreground limit and finished in the background; its log and PDFs are complete.

`s85builder.mts`:

```ts
// Session 85 (2026-10-28): three open Word questions, on the minimal package (`tests/support/minimal-docx.ts`).
// s85a/s85b, #1145 and #1146: does Word read a footnotes, endnotes or comments part the main document relates when the
//   part's only reference sits in a used header? Each part's root carries mc:MustUnderstand="foo" for an unknown urn:foo,
//   which Word refused on the main document's root and in a used header (session 84, s84a). Per kind:
//   - `-mu-header-reference`: the part related by the main document, its only reference in a read header (the probe);
//   - `-mu-body-reference`: the same part referenced from the body, the read placement (expected refused);
//   - `-header-reference-calibration`: the header-referenced part without MustUnderstand (session 62's clean shape);
//   - `-mu-unreferenced`: the part related, referenced by nothing (#1125's warning; session 84 showed only a header).
//   s85b adds the footer twin of s84a's unused and used header (`footer-mu-unused`, `footer-mu-used`).
// s85c, #1127: does Word read a part an internal target names through a scheme-like spelling (`ftp:`, `httpfoo:`)?
//   - `header-ftp-unclosed` / `header-httpfoo-unclosed`: a used header related by `Target="ftp:header1.xml"` /
//     `"httpfoo:header1.xml"`, stored as `word/ftp:header1.xml` / `word/httpfoo:header1.xml` with an unclosed root;
//   - `-wellformed` twins with the same header closed;
//   - `styles-ftp-unclosed` / `styles-ftp-wellformed`: the styles relationship retargeted to `ftp:styles.xml`, the part
//     stored as `word/ftp:styles.xml`;
//   - `header-plain-unclosed` / `styles-plain-unclosed`: the unclosed parts through plain names (expected refused).
// s85e, #1127 follow-up, added after s85c's first run refused every scheme-like row, well-formed too: is it the colon
//   in the stored part name or the scheme in the target?
//   - `colon-part-unrelated`: the minimal package plus a well-formed `word/ftp:header1.xml`, typed header by its
//     Override, named by no relationship;
//   - `colon-part-default-type`: the same part with no Override (the `xml` Default types it);
//   - `ftp-target-plain-part` / `httpfoo-target-plain-part`: a used header related by `Target="ftp:header1.xml"` /
//     `"httpfoo:header1.xml"`, stored as plain `word/header1.xml`;
//   - `header-dotslash-ftp-wellformed`: the well-formed `word/ftp:header1.xml` used through `Target="./ftp:header1.xml"`,
//     the spelling that names it without a scheme.
// s85d, #1136: does an unclosed relationships part Word never reads matter? s84a's `mu-stray-foo` (Word opened it clean)
//   plus an unclosed `word/_rels/stray.xml.rels` with no source part, or plus `word/x.xml` (a stray part no relationship
//   names) with an unclosed `word/_rels/x.xml.rels`; each broken sidecar alone; `mu-stray-foo` repeated.
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run from the worktree root, with the tree committed: CHUNK=s85a pnpm exec node --import tsx <abs path to this file>
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const MU = ` xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo"`;
const TEXT_P = "<w:p><w:r><w:t>Text 85</w:t></w:r></w:p>";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
/** `parts` with `r:` declared on the main document, `run` appended inside its only paragraph and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` plus a part related by the main document as `segment`, typed `type`. */
const withRelated = (
    parts: Record<string, string>,
    name: string,
    xml: string,
    id: string,
    segment: string,
    type: string,
    target = name,
) => ({
    ...parts,
    [`word/${name}`]: xml,
    [SIDECAR]: appendRels(parts[SIDECAR]!, relationship(id, segment, target)),
    [CT]: overrides(parts[CT]!, [`word/${name}`, type]),
});

// s85a/s85b
type Story = "footnote" | "endnote" | "comment";
const storyXml = (kind: Story, mu: boolean) =>
    kind === "comment"
        ? `${XML_DECL}<w:comments xmlns:w="${W}"${mu ? MU : ""}><w:comment w:id="0" w:author="a">${TEXT_P}</w:comment></w:comments>`
        : `${XML_DECL}<w:${kind}s xmlns:w="${W}"${mu ? MU : ""}><w:${kind} w:id="1">${TEXT_P}</w:${kind}></w:${kind}s>`;
const storyRef = (kind: Story) =>
    kind === "comment" ? `<w:r><w:commentReference w:id="0"/></w:r>` : `<w:r><w:${kind}Reference w:id="1"/></w:r>`;
/** The minimal parts with `word/<kind>s.xml` related by the main document, its root carrying MustUnderstand when `mu`. */
const withStory = (kind: Story, mu: boolean) =>
    withRelated(P, `${kind}s.xml`, storyXml(kind, mu), "rIdS", `${kind}s`, `${WML}.${kind}s+xml`);
/** `parts` with a read header (`word/header1.xml`, referenced by the section) holding `run` in its paragraph. */
const withReadHeader = (parts: Record<string, string>, run: string) =>
    mainWith(
        withRelated(
            parts,
            "header1.xml",
            `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header 85</w:t></w:r>${run}</w:p></w:hdr>`,
            "rIdH",
            "header",
            `${WML}.header+xml`,
        ),
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );
const storyRows = (kind: Story): Row[] => [
    [
        `${kind}s-mu-header-reference`,
        `#1145: word/${kind}s.xml related by the main document, root MustUnderstand urn:foo, its only reference in a read header`,
        () => buildDocx(withReadHeader(withStory(kind, true), storyRef(kind))),
    ],
    [
        `${kind}s-mu-body-reference`,
        `#1145 calibration: the same part referenced from the body`,
        () => buildDocx(mainWith(withStory(kind, true), storyRef(kind))),
    ],
    [
        `${kind}s-header-reference-calibration`,
        `calibration: the header-referenced part without MustUnderstand`,
        () => buildDocx(withReadHeader(withStory(kind, false), storyRef(kind))),
    ],
    [
        `${kind}s-mu-unreferenced`,
        `#1146: the MustUnderstand part related by the main document, referenced by nothing`,
        () => buildDocx(withStory(kind, true)),
    ],
];
const footerXml = `${XML_DECL}<w:ftr xmlns:w="${W}"${MU}><w:p><w:r><w:t>Footer 85</w:t></w:r></w:p></w:ftr>`;
const withFooter = (used: boolean) => {
    const parts = withRelated(P, "footer1.xml", footerXml, "rIdF", "footer", `${WML}.footer+xml`);
    return used ? mainWith(parts, "", `<w:footerReference w:type="default" r:id="rIdF"/>`) : parts;
};

// s85c
const headerXml = (closed: boolean) =>
    `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header 85</w:t></w:r></w:p>${closed ? "</w:hdr>" : ""}`;
/** A used header related by `Target="<target>"` and stored as `word/<target>`. */
const usedHeaderAt = (target: string, closed: boolean) =>
    mainWith(
        withRelated(P, target, headerXml(closed), "rIdH", "header", `${WML}.header+xml`),
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );
/** A used header related by `Target="<target>"`, stored as `word/<stored>`. */
const usedHeaderStoredAs = (target: string, stored: string) => {
    const parts = usedHeaderAt(stored, true);
    return { ...parts, [SIDECAR]: replaceOnce(parts[SIDECAR]!, `Target="${stored}"`, `Target="${target}"`) };
};
/** The minimal package plus a well-formed `word/ftp:header1.xml` no relationship names, typed header unless `untyped`. */
const colonPart = (untyped: boolean) => {
    const parts: Record<string, string> = { ...P, "word/ftp:header1.xml": headerXml(true) };
    if (!untyped) parts[CT] = overrides(P[CT]!, ["word/ftp:header1.xml", `${WML}.header+xml`]);
    return parts;
};
/** The styles part stored as `word/<target>` and related by `Target="<target>"`, its root closed or not. */
const stylesAt = (target: string, closed: boolean) => {
    const styles = closed ? P["word/styles.xml"]! : replaceOnce(P["word/styles.xml"]!, "</w:styles>", "");
    const parts: Record<string, string> = { ...P, [`word/${target}`]: styles };
    if (target !== "styles.xml") {
        delete parts["word/styles.xml"];
        parts[SIDECAR] = replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`);
        parts[CT] = replaceOnce(P[CT]!, 'PartName="/word/styles.xml"', `PartName="/word/${target}"`);
    }
    return parts;
};

// s85d
const STRAY_FOO = (mu: boolean) => `${XML_DECL}<w:document xmlns:w="${W}"${mu ? MU : ""}><w:body/></w:document>`;
const UNCLOSED_RELS = `${XML_DECL}<Relationships xmlns="${PR}">`;
const strayParts = (fooMu: boolean | undefined, sidecar: "stray" | "x" | undefined) => {
    const parts: Record<string, string> = { ...P };
    if (fooMu !== undefined) parts["word/foo.xml"] = STRAY_FOO(fooMu);
    if (sidecar === "stray") parts["word/_rels/stray.xml.rels"] = UNCLOSED_RELS;
    if (sidecar === "x") {
        parts["word/x.xml"] = STRAY_FOO(false);
        parts["word/_rels/x.xml.rels"] = UNCLOSED_RELS;
    }
    return parts;
};

type Row = [string, string, () => Promise<Uint8Array>];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s85a: withControl("s85a", [...storyRows("footnote"), ...storyRows("endnote")]),
    s85b: withControl("s85b", [
        ...storyRows("comment"),
        [
            "footer-mu-unused",
            "#1146: word/footer1.xml related by the main document, referenced by nothing, root MustUnderstand urn:foo",
            () => buildDocx(withFooter(false)),
        ],
        ["footer-mu-used", "calibration: the same footer referenced by the section", () => buildDocx(withFooter(true))],
    ]),
    s85c: withControl("s85c", [
        [
            "header-ftp-unclosed",
            '#1127: a used header related by Target="ftp:header1.xml", stored as word/ftp:header1.xml with an unclosed root',
            () => buildDocx(usedHeaderAt("ftp:header1.xml", false)),
        ],
        ["header-ftp-wellformed", "#1127 twin: the same header closed", () => buildDocx(usedHeaderAt("ftp:header1.xml", true))],
        [
            "header-httpfoo-unclosed",
            '#1127: a used header related by Target="httpfoo:header1.xml", stored as word/httpfoo:header1.xml with an unclosed root',
            () => buildDocx(usedHeaderAt("httpfoo:header1.xml", false)),
        ],
        ["header-httpfoo-wellformed", "#1127 twin: the same header closed", () => buildDocx(usedHeaderAt("httpfoo:header1.xml", true))],
        [
            "styles-ftp-unclosed",
            '#1127: the styles relationship\'s Target "ftp:styles.xml", the part stored as word/ftp:styles.xml with an unclosed root',
            () => buildDocx(stylesAt("ftp:styles.xml", false)),
        ],
        ["styles-ftp-wellformed", "#1127 twin: the same styles part closed", () => buildDocx(stylesAt("ftp:styles.xml", true))],
        [
            "header-plain-unclosed",
            'calibration: the unclosed used header related by Target="header1.xml"',
            () => buildDocx(usedHeaderAt("header1.xml", false)),
        ],
        [
            "styles-plain-unclosed",
            "calibration: the minimal word/styles.xml with an unclosed root",
            () => buildDocx(stylesAt("styles.xml", false)),
        ],
    ]),
    s85e: withControl("s85e", [
        [
            "colon-part-unrelated",
            "#1127 follow-up: minimal plus a well-formed word/ftp:header1.xml, typed header, named by no relationship",
            () => buildDocx(colonPart(false)),
        ],
        ["colon-part-default-type", "#1127 follow-up: the same part with no Override", () => buildDocx(colonPart(true))],
        [
            "ftp-target-plain-part",
            '#1127 follow-up: a used header related by Target="ftp:header1.xml", stored as word/header1.xml',
            () => buildDocx(usedHeaderStoredAs("ftp:header1.xml", "header1.xml")),
        ],
        [
            "httpfoo-target-plain-part",
            '#1127 follow-up: a used header related by Target="httpfoo:header1.xml", stored as word/header1.xml',
            () => buildDocx(usedHeaderStoredAs("httpfoo:header1.xml", "header1.xml")),
        ],
        [
            "header-dotslash-ftp-wellformed",
            '#1127 follow-up: the well-formed word/ftp:header1.xml used through Target="./ftp:header1.xml"',
            () => buildDocx(usedHeaderStoredAs("./ftp:header1.xml", "ftp:header1.xml")),
        ],
    ]),
    s85d: withControl("s85d", [
        [
            "mu-stray-foo-broken-stray-sidecar",
            "#1136: s84a's mu-stray-foo plus an unclosed word/_rels/stray.xml.rels with no word/stray.xml",
            () => buildDocx(strayParts(true, "stray")),
        ],
        [
            "mu-stray-foo-broken-x-sidecar",
            "#1136: s84a's mu-stray-foo plus word/x.xml (no Override, no relationship) and an unclosed word/_rels/x.xml.rels",
            () => buildDocx(strayParts(true, "x")),
        ],
        ["mu-stray-foo", "#1136 calibration: s84a's mu-stray-foo repeated", () => buildDocx(strayParts(true, undefined))],
        [
            "broken-stray-sidecar-only",
            "#1136 calibration: the unclosed word/_rels/stray.xml.rels alone",
            () => buildDocx(strayParts(undefined, "stray")),
        ],
        [
            "broken-x-sidecar-only",
            "#1136 calibration: word/x.xml with its unclosed sidecar alone",
            () => buildDocx(strayParts(undefined, "x")),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`compare.py`:

```python
"""Join both passes of the session-85 chunks: log verdicts, table verdicts, validator verdicts, hashes."""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s85a", "s85b", "s85c", "s85d", "s85e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    passes = []
    for run in (ROOT / label, ROOT / label / "pass2"):
        for name, spec in specs.items():
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        passes.append({json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()})
    assert set(passes[0]) == set(passes[1]) == set(specs), label
    for name, spec in specs.items():
        p1, p2 = passes[0][name], passes[1][name]
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "readings": readings, "agreed": agreed,
                     "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     # A match needs agreed readings: an unknown row matches nothing (CodeRabbit on #985).
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s85/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<58} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-85 part of docs/plans/evidence/word-probes-2026-10-24.md into s85/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
both runs' logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. The validator label comes from
the rows' `validatorRevision`, never from this script (CodeRabbit on #796). The text Word rendered is read from its own
PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s85a", "s85b", "s85c", "s85d", "s85e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s85/results.json").read_text())}


def cell(v):
    # A builder records valid: null when validate() threw; render that as the exception, not as a rejection.
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def strict_cell(v):
    # Strict also reports the specimens' unreferenced-part, paraId, content-type and XSD findings; the column names the
    # markup-compatibility, XML-syntax and relationship findings, the ones this session probes, and every other code
    # only by count.
    if v["valid"] is None:
        return cell(v)
    if v["valid"]:
        return "valid"
    probed = [e for e in v["errors"] if e.startswith(("mce-", "xml-", "rels-"))]
    rest = len(v["errors"]) - len(probed)
    named = ", ".join(f"`{e}`" for e in probed)
    if rest:
        named = f"{named}{', ' if named else ''}{rest} other finding{'s' if rest > 1 else ''}"
    return "invalid: " + named


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    runs = [ROOT / label, ROOT / label / "pass2"]
    checks = [{json.loads(l)["file"]: json.loads(l) for l in (r / "logcheck.jsonl").read_text().splitlines()} for r in runs]
    for s in specs:
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        result = results[(label, s["file"])]
        agreed += result["agreed"]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(checks[0][s['file']])} | {word_cell(checks[1][s['file']])} | {result['outcome']} | {cell(s['wordValid'])} | {strict_cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, checks, times), start=1):
            row = c[s["file"]]
            record = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"],
                      "validatorRevision": s.get("validatorRevision"), "observedAt": t.isoformat(),
                      "staged": row["staged"], "logVerdict": row["logVerdict"], "tableVerdict": row["outcomesVerdict"],
                      "pdf": row["pdf"], "evidence": row["evidence"]}
            error = manifest(r, s["file"]).get("error")
            if error:
                record["error"] = error
            raw.append(json.dumps(record, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8] if rev != "unknown" else "an unrecorded revision"

# Rows Word refused (every reading a rejection) and rows holding a markup-compatibility finding word-valid judges.
REFUSED = {"footnotes-mu-body-reference.docx", "endnotes-mu-body-reference.docx", "comments-mu-body-reference.docx",
           "footer-mu-used.docx", "header-ftp-unclosed.docx", "header-ftp-wellformed.docx", "header-httpfoo-unclosed.docx",
           "header-httpfoo-wellformed.docx", "styles-ftp-unclosed.docx", "styles-ftp-wellformed.docx",
           "header-plain-unclosed.docx", "styles-plain-unclosed.docx", "colon-part-unrelated.docx",
           "colon-part-default-type.docx", "ftp-target-plain-part.docx", "httpfoo-target-plain-part.docx",
           "header-dotslash-ftp-wellformed.docx"}
OPEN_ERROR = {"header-plain-unclosed.docx"}
# The narrative's claims, checked against results.json: every row's four readings agree; Word refused exactly REFUSED,
# with an open error for the unclosed plain header and a recovery offer for the rest, and opened every other row clean;
# word-valid at the probed revision is wrong on exactly the rows named below.
WRONG = {"footnotes-mu-header-reference.docx", "endnotes-mu-header-reference.docx", "comments-mu-header-reference.docx",
         "mu-stray-foo-broken-stray-sidecar.docx", "mu-stray-foo-broken-x-sidecar.docx", "header-ftp-unclosed.docx",
         "header-ftp-wellformed.docx", "header-httpfoo-unclosed.docx", "header-httpfoo-wellformed.docx",
         "styles-ftp-unclosed.docx", "styles-ftp-wellformed.docx", "colon-part-unrelated.docx", "colon-part-default-type.docx",
         "ftp-target-plain-part.docx", "httpfoo-target-plain-part.docx", "header-dotslash-ftp-wellformed.docx"}
for (label, file), r in results.items():
    assert r["agreed"], (label, file, r)
    if file in REFUSED:
        expected = "open-error" if file in OPEN_ERROR else "unreadable-content-warning"
        assert r["everyReadingRejects"] and r["outcome"] == expected, (label, file, r)
    else:
        assert set(r["readings"]) == {"clean-open"}, (label, file, r)
    assert r["validatorMatchesWord"] is (file not in WRONG), (label, file, r)
assert agreed == len(rows) == 37, (agreed, len(rows))
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == files, (run, opened)
# The text Word rendered, both runs: a row with a read header renders the header's "Header 85" and the main document's
# "Hello", and never a note's or comment's "Text 85"; every other row Word opened renders "Hello"; a refused row left no
# PDF.
texts = {}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2"):
        for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
            file = json.loads(line)["original_filename"]
            text = rendered(run, file)
            texts.setdefault(file, set()).add(text)
            if file in REFUSED:
                assert text is None, (run, file, text)
for file, seen in texts.items():
    if file in REFUSED:
        continue
    assert seen == ({"Header 85 Hello"} if "header-reference" in file else {"Hello"}), (file, seen)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 85: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    "Three open questions, on the minimal package. Five chunks; s85e was added after s85c's first run.",
    "",
    f"- **s85a and s85b, [#1145]({I}1145).** Does Word read a footnotes, endnotes or comments part the main document "
    "relates when the part's only reference sits in a used header? Each part's root carries `mc:MustUnderstand=\"foo\"` "
    "for an unknown `urn:foo`, which Word refused on the main document's root and in a used header (session 84). Per "
    "kind: `-mu-header-reference` has a read header (`word/header1.xml`, referenced by the section) hold the part's "
    "only reference; `-mu-body-reference` references the same part from the body; `-header-reference-calibration` is "
    "the header-referenced part without the attribute; `-mu-unreferenced` relates the part and references it nowhere. "
    "s85b adds a footer holding the attribute, related and unused (`footer-mu-unused`) or referenced by the section "
    "(`footer-mu-used`).",
    f"- **s85c and s85e, [#1127]({I}1127).** Does Word read a part an internal target names through a scheme-like "
    "spelling? s85c relates a used header through `Target=\"ftp:header1.xml\"` or `\"httpfoo:header1.xml\"`, stored as "
    "`word/ftp:header1.xml` or `word/httpfoo:header1.xml`, and the styles part through `ftp:styles.xml`, each with an "
    "unclosed root and `-wellformed`; the plain-name twins of the unclosed header and styles part are calibrations. "
    "s85e separates the stored name from the target: `colon-part-unrelated` stores a well-formed "
    "`word/ftp:header1.xml`, typed header and named by no relationship, and `colon-part-default-type` the same part "
    "with no Override; `ftp-target-plain-part` and `httpfoo-target-plain-part` relate a used header through the "
    "scheme-like target while the part is stored as plain `word/header1.xml`; `header-dotslash-ftp-wellformed` uses "
    "the stored `word/ftp:header1.xml` through `Target=\"./ftp:header1.xml\"`, which names it without a scheme.",
    f"- **s85d, [#1136]({I}1136).** Does an unclosed relationships part Word never reads matter? Session 84's "
    "`mu-stray-foo` plus an unclosed `word/_rels/stray.xml.rels` with no source part, or plus a stray `word/x.xml` "
    "with an unclosed `word/_rels/x.xml.rels`; each broken sidecar alone; and `mu-stray-foo` again.",
    "",
    "Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed are the ends of the first and second runs. "
    f"Shape is the builder's description of the specimen. The builder recorded the validator revision in every row "
    f"(`{rev}`). The strict column names the markup-compatibility, XML-syntax and relationship findings, and counts the "
    "others.",
    "",
    "Every calibration Word was meant to open, and every control, opened clean. Every row Word opened renders the main "
    "document's `Hello` in both runs (`pdftotext`), after the header's `Header 85` where the section references a "
    "header, and never a note's or comment's `Text 85`. No refused row left a PDF.",
    "",
    "- **Word does not read a notes or comments part whose only reference is in a header.** It opened clean all three "
    "`-mu-header-reference` rows, and offered to recover unreadable content for the same parts referenced from the "
    "body. It opened clean the related, unreferenced part of each kind and the unused footer, and refused the used "
    "footer.",
    "- **Word refuses a stored part name holding a colon, read or not.** It offered recovery for `word/ftp:header1.xml` "
    "named by no relationship, with or without its Override, and for every scheme-like s85c row, well-formed or not. "
    "The unclosed plain-name header drew an open error and the unclosed plain styles part a recovery offer.",
    "- **It refuses a used header whose target spells a scheme, too.** With the part stored as plain "
    "`word/header1.xml` and no colon in any stored name, `Target=\"ftp:header1.xml\"` and `\"httpfoo:header1.xml\"` "
    "drew the recovery offer. These rows do not show whether Word reads the target as a missing part or refuses the "
    "spelling.",
    "- **A broken relationships part Word never reads does not matter.** It opened clean every s85d row, "
    "`mu-stray-foo` beside either broken sidecar included.",
    "",
    f"Word-valid at {at} matches Word on {matches} of {len(rows)} rows. It rejects the three header-only rows Word opened "
    f"clean ([#1145]({I}1145)'s conservative half, narrowed back by [#1155]({I}1155)) and the two `mu-stray-foo` rows "
    f"beside a broken sidecar ([#1136]({I}1136)). It passes the eleven scheme-like and colon rows Word refused.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 85</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 85 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. "
    "The builder ran in the committed worktree, `WT` naming it. s85c's first run outlasted the 10-minute foreground "
    "limit and finished in the background; its log and PDFs are complete.",
    "",
]
for name, path, lang in (("s85builder.mts", ROOT / "s85builder.mts", "ts"), ("compare.py", ROOT / "s85/compare.py", "python"),
                         ("section.py", ROOT / "s85/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s85/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 86: 18:05Z–18:23Z on 2026-10-28, validator columns at ddf9a18f

The placements [#1155](https://github.com/jandira-tech/docx-validate/issues/1155) and [#1158](https://github.com/jandira-tech/docx-validate/issues/1158) decide by the read model, which sessions 34, 84 and 85 bracket but did not show Word ([#1164](https://github.com/jandira-tech/docx-validate/issues/1164), review 1156 F4). Three chunks, on the minimal package. Every `mc:MustUnderstand="foo"` names an unknown `urn:foo`, which Word refused in a read header and in a body-referenced notes or comments part (sessions 84 and 85).

- **s86a, [#1155](https://github.com/jandira-tech/docx-validate/issues/1155).** A footnotes, endnotes or comments part the main document relates, with the attribute on its root, whose only reference sits in a used footer (`-mu-footer-reference`). The same part referenced from the body (`-mu-body-reference`) and the footer-referenced part without the attribute (`-footer-reference-calibration`) are calibrations.
- **s86b, [#1155](https://github.com/jandira-tech/docx-validate/issues/1155).** The main document relates `word/glossary/document.xml`, whose docPartBody `w:sectPr` uses `word/glossary/header1.xml` (session 26's glossaryRef shape). `glossary-header-mu-used` puts the attribute on that header, to show whether Word reads it; `glossary-header-calibration` leaves it off. Per kind, the glossary relates a part with the attribute whose only reference sits in that header (`glossary-<kind>s-mu-header-reference`) or in the docPartBody (`-mu-body-reference`).
- **s86c, [#1155](https://github.com/jandira-tech/docx-validate/issues/1155) and [#1158](https://github.com/jandira-tech/docx-validate/issues/1158).** `footnotes-malformed-header-reference` puts an undeclared-`Requires` Choice (`mce-malformed`) in a footnotes part whose only reference sits in a read header; `-body-reference` is its calibration. The `header-mu-` rows relate a header with the attribute through a relationship inside a selected `mc:Fallback`, or an understood `mc:Choice` (`Requires="w14"`), of the main document's relationships part, the header unused or referenced by the section.

Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. The first s86c run left no evidence for `header-mu-used-fallback`: the driver's AppleEvent timed out. That row ran a third time from byte-identical bytes, beside the control, and its two runs below are the second and third; the raw records keep the first, marked excluded. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 26 of 26 rows agree. The two times in Observed are the ends of the row's two runs. Shape is the builder's description of the specimen. The builder recorded the validator revision in every row (`ddf9a18ffec7a8e683c68d02e79a970b4da797c8`). The strict column names the markup-compatibility, XML-syntax and relationship findings, and counts the others.

Every calibration Word was meant to open, and every control, opened clean. Every row Word opened renders the main document's `Hello` (`pdftotext`), after `Header 86` where the section uses a header and before `Footer 86` where it uses a footer. No glossary text and no note's or comment's `Text 86` renders. No refused row left a PDF.

- **Word does not read a notes or comments part whose only reference is in a footer either.** It opened clean all three `-mu-footer-reference` rows, and offered to recover unreadable content for the same parts referenced from the body.
- **Word reads a reached glossary's used header, and not a notes or comments part only that header references.** It offered recovery for `glossary-header-mu-used`, opened clean the three glossary `-mu-header-reference` rows, and offered recovery for the same parts referenced from the docPartBody.
- **Malformed compatibility follows the same rule.** Word opened clean the undeclared-`Requires` Choice in a footnotes part only a read header references, and offered recovery for it referenced from the body.
- **A relationship markup compatibility selects relates a header as a direct one does.** Word opened clean the header related through a selected Fallback or an understood Choice and unused, and offered recovery for each used.

Word-valid at ddf9a18f matches Word on 26 of 26 rows. At 07450f03, before [#1158](https://github.com/jandira-tech/docx-validate/issues/1158), it rejected `header-mu-unused-fallback` and `header-mu-unused-choice` (`mce-must-understand` an error in `word/header1.xml`), both of which Word opened clean.

| Run    | Observed             | Specimen                                 | Shape                                                                                                                                        | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at ddf9a18f                                                                            | strict at ddf9a18f                                                           |
| ------ | -------------------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `s86a` | 18:05:15Z, 18:09:13Z | `footnotes-mu-footer-reference`          | #1155: word/footnotes.xml related by the main document, root MustUnderstand urn:foo, its only reference in a used footer                     | `8ee465bc5df9fa8b` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/footnotes.xml`, 2 other findings          |
| `s86a` | 18:05:15Z, 18:09:13Z | `footnotes-mu-body-reference`            | calibration: the same part referenced from the body                                                                                          | `af444af145193d0b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/footnotes.xml`                                                 | invalid: `mce-must-understand@word/footnotes.xml`, 1 other finding           |
| `s86a` | 18:05:15Z, 18:09:13Z | `footnotes-footer-reference-calibration` | calibration: the footer-referenced part without MustUnderstand                                                                               | `79501003bcd0051a` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: 2 other findings                                                    |
| `s86a` | 18:05:15Z, 18:09:13Z | `endnotes-mu-footer-reference`           | #1155: word/endnotes.xml related by the main document, root MustUnderstand urn:foo, its only reference in a used footer                      | `e7dc40ecd8f1a297` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/endnotes.xml`, 2 other findings           |
| `s86a` | 18:05:15Z, 18:09:13Z | `endnotes-mu-body-reference`             | calibration: the same part referenced from the body                                                                                          | `62cc50ba21a707aa` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/endnotes.xml`                                                  | invalid: `mce-must-understand@word/endnotes.xml`, 1 other finding            |
| `s86a` | 18:05:15Z, 18:09:13Z | `endnotes-footer-reference-calibration`  | calibration: the footer-referenced part without MustUnderstand                                                                               | `d9804b1624cac899` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: 2 other findings                                                    |
| `s86a` | 18:05:15Z, 18:09:13Z | `comments-mu-footer-reference`           | #1155: word/comments.xml related by the main document, root MustUnderstand urn:foo, its only reference in a used footer                      | `0622279f7f289b19` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/comments.xml`, 3 other findings           |
| `s86a` | 18:05:15Z, 18:09:13Z | `comments-mu-body-reference`             | calibration: the same part referenced from the body                                                                                          | `88fc06231c25146c` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/comments.xml`                                                  | invalid: `mce-must-understand@word/comments.xml`, 2 other findings           |
| `s86a` | 18:05:15Z, 18:09:13Z | `comments-footer-reference-calibration`  | calibration: the footer-referenced part without MustUnderstand                                                                               | `34a4677d450099fa` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: 3 other findings                                                    |
| `s86a` | 18:05:15Z, 18:09:13Z | `s86a-control-minimal`                   | control                                                                                                                                      | `ce2c24e646762abd` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | valid                                                                        |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-header-mu-used`                | calibration: the reached glossary's used header with root MustUnderstand urn:foo                                                             | `a78f998198c54d1c` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/glossary/header1.xml`                                          | invalid: `mce-must-understand@word/glossary/header1.xml`, 2 other findings   |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-header-calibration`            | calibration: the reached glossary and its used header, no MustUnderstand                                                                     | `48968bcecb032185` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: 2 other findings                                                    |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-footnotes-mu-header-reference` | #1155: a reached glossary relates word/glossary/footnotes.xml, root MustUnderstand urn:foo, its only reference in the glossary's used header | `90c32b9357d6b0c3` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/glossary/footnotes.xml`, 3 other findings |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-footnotes-mu-body-reference`   | calibration: the same part referenced from the glossary's docPartBody                                                                        | `b51e56bd24da8b2d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/glossary/footnotes.xml`                                        | invalid: `mce-must-understand@word/glossary/footnotes.xml`, 3 other findings |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-endnotes-mu-header-reference`  | #1155: a reached glossary relates word/glossary/endnotes.xml, root MustUnderstand urn:foo, its only reference in the glossary's used header  | `d7f7863020dc7b19` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/glossary/endnotes.xml`, 3 other findings  |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-endnotes-mu-body-reference`    | calibration: the same part referenced from the glossary's docPartBody                                                                        | `c6b27992a3a6237d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/glossary/endnotes.xml`                                         | invalid: `mce-must-understand@word/glossary/endnotes.xml`, 3 other findings  |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-comments-mu-header-reference`  | #1155: a reached glossary relates word/glossary/comments.xml, root MustUnderstand urn:foo, its only reference in the glossary's used header  | `99d7efe37eb7c18c` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/glossary/comments.xml`, 3 other findings  |
| `s86b` | 18:12:15Z, 18:14:38Z | `glossary-comments-mu-body-reference`    | calibration: the same part referenced from the glossary's docPartBody                                                                        | `5c97cf181c69db20` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/glossary/comments.xml`                                         | invalid: `mce-must-understand@word/glossary/comments.xml`, 3 other findings  |
| `s86b` | 18:12:15Z, 18:14:38Z | `s86b-control-minimal`                   | control                                                                                                                                      | `1fdfc93382f9fb4e` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | valid                                                                        |
| `s86c` | 18:20:27Z, 18:22:17Z | `footnotes-malformed-header-reference`   | #1155: word/footnotes.xml holding an undeclared-Requires Choice, its only reference in a read header                                         | `8d44233267ef95a0` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-malformed@word/footnotes.xml`, 2 other findings                |
| `s86c` | 18:20:27Z, 18:22:17Z | `footnotes-malformed-body-reference`     | calibration: the same part referenced from the body                                                                                          | `df977144dd0d81b6` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-malformed@word/footnotes.xml`, `word-choice-requires-undeclared@word/footnotes.xml` | invalid: `mce-malformed@word/footnotes.xml`, 2 other findings                |
| `s86c` | 18:20:27Z, 18:22:17Z | `header-mu-unused-fallback`              | #1158: a MustUnderstand header related through a relationship inside a selected mc:Fallback, unused                                          | `41c624faaeb00d26` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/header1.xml`, 2 other findings            |
| `s86c` | 18:22:17Z, 18:23:31Z | `header-mu-used-fallback`                | calibration: the same header used                                                                                                            | `c810ce29bb589a8b` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/header1.xml`                                                   | invalid: `mce-must-understand@word/header1.xml`, 2 other findings            |
| `s86c` | 18:20:27Z, 18:22:17Z | `header-mu-unused-choice`                | #1158: the header related through an understood mc:Choice (Requires="w14"), unused                                                           | `dd6c542b5aaa3d3e` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | invalid: `mce-must-understand@word/header1.xml`, 2 other findings            |
| `s86c` | 18:20:27Z, 18:22:17Z | `header-mu-used-choice`                  | calibration: the same header used                                                                                                            | `12495fc0640830fe` | repair-warning | repair-warning | unreadable-content-warning | invalid: `mce-must-understand@word/header1.xml`                                                   | invalid: `mce-must-understand@word/header1.xml`, 2 other findings            |
| `s86c` | 18:20:27Z, 18:22:17Z | `s86c-control-minimal`                   | control                                                                                                                                      | `fc4290bd6a17ce1c` | clean-open     | clean-open     | clean-open                 | valid                                                                                             | valid                                                                        |

<details><summary>Raw records, session 86</summary>

```jsonl
{"run": "s86a", "pass": 1, "name": "footnotes-mu-footer-reference", "sha256": "8ee465bc5df9fa8b1ad05e84ee957b66aead9a283b8b85530e5342b36ba4dbce", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00008__wfv__footnotes-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "footnotes-mu-footer-reference", "sha256": "8ee465bc5df9fa8b1ad05e84ee957b66aead9a283b8b85530e5342b36ba4dbce", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00008__wfv__footnotes-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "footnotes-mu-body-reference", "sha256": "af444af145193d0baabb068e80761e4943ef05203e4f8fea3ffb2c25d375002d", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00007__wfv__footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:05:14.209 \"Word found unreadable content in 00007__wfv__footnotes-mu-body-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__footnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 2, "name": "footnotes-mu-body-reference", "sha256": "af444af145193d0baabb068e80761e4943ef05203e4f8fea3ffb2c25d375002d", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00007__wfv__footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:09:11.330 \"Word found unreadable content in 00007__wfv__footnotes-mu-body-reference.docx. Do you want to recov … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__footnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 1, "name": "footnotes-footer-reference-calibration", "sha256": "79501003bcd0051a1891fbe347a2a942cf3424b3708e8a7eeefa4b0628f56448", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00006__wfv__footnotes-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "footnotes-footer-reference-calibration", "sha256": "79501003bcd0051a1891fbe347a2a942cf3424b3708e8a7eeefa4b0628f56448", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00006__wfv__footnotes-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "endnotes-mu-footer-reference", "sha256": "e7dc40ecd8f1a29770338ec9f6fd88923cba167b0011baa2f955e5edbcfe5a44", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00005__wfv__endnotes-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "endnotes-mu-footer-reference", "sha256": "e7dc40ecd8f1a29770338ec9f6fd88923cba167b0011baa2f955e5edbcfe5a44", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00005__wfv__endnotes-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "endnotes-mu-body-reference", "sha256": "62cc50ba21a707aa99d162407db0750dfa1b34479877fcc05c1de5fcfc7557a0", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00004__wfv__endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:04:58.124 \"Word found unreadable content in 00004__wfv__endnotes-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__endnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 2, "name": "endnotes-mu-body-reference", "sha256": "62cc50ba21a707aa99d162407db0750dfa1b34479877fcc05c1de5fcfc7557a0", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00004__wfv__endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:06:21.682 \"Word found unreadable content in 00004__wfv__endnotes-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__endnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 1, "name": "endnotes-footer-reference-calibration", "sha256": "d9804b1624cac899e080cb32995380f7345e95bc0133b86d5907b0a60e5b06e1", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00003__wfv__endnotes-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "endnotes-footer-reference-calibration", "sha256": "d9804b1624cac899e080cb32995380f7345e95bc0133b86d5907b0a60e5b06e1", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00003__wfv__endnotes-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF endnotes-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "comments-mu-footer-reference", "sha256": "0622279f7f289b19442afe927585e1a3459acde9565d4dfe24f86fc4692acb03", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00002__wfv__comments-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "comments-mu-footer-reference", "sha256": "0622279f7f289b19442afe927585e1a3459acde9565d4dfe24f86fc4692acb03", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00002__wfv__comments-mu-footer-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-mu-footer-reference_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "comments-mu-body-reference", "sha256": "88fc06231c25146c48d62e3e814db2c71bbc96129d693a3348f376c4087caff9", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00001__wfv__comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:04:40.121 \"Word found unreadable content in 00001__wfv__comments-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__comments-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 2, "name": "comments-mu-body-reference", "sha256": "88fc06231c25146c48d62e3e814db2c71bbc96129d693a3348f376c4087caff9", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00001__wfv__comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:05:56.810 \"Word found unreadable content in 00001__wfv__comments-mu-body-reference.docx. Do you want to recove … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__comments-mu-body-reference.docx; refusing to guess"}
{"run": "s86a", "pass": 1, "name": "comments-footer-reference-calibration", "sha256": "34a4677d450099fa7f644a58a2d69b9d5f0ec431793dce93a5ec362fb90717c9", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00000__wfv__comments-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "comments-footer-reference-calibration", "sha256": "34a4677d450099fa7f644a58a2d69b9d5f0ec431793dce93a5ec362fb90717c9", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00000__wfv__comments-footer-reference-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-footer-reference-calibration_byword.pdf (15673 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 1, "name": "s86a-control-minimal", "sha256": "ce2c24e646762abd0788f47fd1366d2e2c040ba74399d51b3e691294824359f1", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:05:15+00:00", "staged": "00009__wfv__s86a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86a", "pass": 2, "name": "s86a-control-minimal", "sha256": "ce2c24e646762abd0788f47fd1366d2e2c040ba74399d51b3e691294824359f1", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:09:13+00:00", "staged": "00009__wfv__s86a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 1, "name": "glossary-header-mu-used", "sha256": "a78f998198c54d1c6e7e9649a23aa15de7700eb795dc635a2e0b896d0e90ad63", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00007__wfv__glossary-header-mu-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:11:23.336 \"Word found unreadable content in 00007__wfv__glossary-header-mu-used.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\"", "2026-10-28 14:12:09.902 Microsoft Word, Word experienced an error trying to open the file. Try these suggestions. * Check th … y converter. (00007__wfv__glossary-header-mu-used.docx)"], "error": "repair prompt declined; Word could not read it"}
{"run": "s86b", "pass": 2, "name": "glossary-header-mu-used", "sha256": "a78f998198c54d1c6e7e9649a23aa15de7700eb795dc635a2e0b896d0e90ad63", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00007__wfv__glossary-header-mu-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:14:37.397 \"Word found unreadable content in 00007__wfv__glossary-header-mu-used.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00007__wfv__glossary-header-mu-used.docx; refusing to guess"}
{"run": "s86b", "pass": 1, "name": "glossary-header-calibration", "sha256": "48968bcecb032185f3cad85a585c0286dea17db5cb7a5b3ad26a7e8190ff0ac4", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00006__wfv__glossary-header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-header-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 2, "name": "glossary-header-calibration", "sha256": "48968bcecb032185f3cad85a585c0286dea17db5cb7a5b3ad26a7e8190ff0ac4", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00006__wfv__glossary-header-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-header-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 1, "name": "glossary-footnotes-mu-header-reference", "sha256": "90c32b9357d6b0c3feee6d5494a5bf6f9c9364d1a7539d150e6895d5cab1cc46", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00005__wfv__glossary-footnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-footnotes-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 2, "name": "glossary-footnotes-mu-header-reference", "sha256": "90c32b9357d6b0c3feee6d5494a5bf6f9c9364d1a7539d150e6895d5cab1cc46", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00005__wfv__glossary-footnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-footnotes-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 1, "name": "glossary-footnotes-mu-body-reference", "sha256": "b51e56bd24da8b2d6b172c034117044d87cf51073ec146fbff3970b550f648ee", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00004__wfv__glossary-footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:11:11.488 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__glossary-footnotes-mu-bod...)'", "2026-10-28 14:11:11.685 \"Word found unreadable content in 00004__wfv__glossary-footnotes-mu-body-reference.docx. Do you want … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__glossary-footnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86b", "pass": 2, "name": "glossary-footnotes-mu-body-reference", "sha256": "b51e56bd24da8b2d6b172c034117044d87cf51073ec146fbff3970b550f648ee", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00004__wfv__glossary-footnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:14:15.493 \"Word found unreadable content in 00004__wfv__glossary-footnotes-mu-body-reference.docx. Do you want … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__glossary-footnotes-mu-body-reference.docx; refusing to guess"}
{"run": "s86b", "pass": 1, "name": "glossary-endnotes-mu-header-reference", "sha256": "d7f7863020dc7b193984aae4c6ce33095a33090b576127c7024db409c606ff95", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00003__wfv__glossary-endnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-endnotes-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 2, "name": "glossary-endnotes-mu-header-reference", "sha256": "d7f7863020dc7b193984aae4c6ce33095a33090b576127c7024db409c606ff95", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00003__wfv__glossary-endnotes-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-endnotes-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 1, "name": "glossary-endnotes-mu-body-reference", "sha256": "c6b27992a3a6237dbd273b18dab1929a54541aa774de8f537eaf027c25ec92e2", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00002__wfv__glossary-endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:10:52.343 'Word found unreadable content in 00002__wfv__glossary-endnotes-mu-body-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-28 14:10:53.082 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__glossary-endnotes-mu-body...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s86b", "pass": 2, "name": "glossary-endnotes-mu-body-reference", "sha256": "c6b27992a3a6237dbd273b18dab1929a54541aa774de8f537eaf027c25ec92e2", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00002__wfv__glossary-endnotes-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:13:44.536 \"Word found unreadable content in 00002__wfv__glossary-endnotes-mu-body-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.\"", "2026-10-28 14:13:55.905 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__glossary-endnotes-mu-body...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s86b", "pass": 1, "name": "glossary-comments-mu-header-reference", "sha256": "99d7efe37eb7c18c5043cbb613230f125d2bb5974cd1e6ff6b9959e6e371e6cb", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00001__wfv__glossary-comments-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-comments-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 2, "name": "glossary-comments-mu-header-reference", "sha256": "99d7efe37eb7c18c5043cbb613230f125d2bb5974cd1e6ff6b9959e6e371e6cb", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00001__wfv__glossary-comments-mu-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF glossary-comments-mu-header-reference_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 1, "name": "glossary-comments-mu-body-reference", "sha256": "5c97cf181c69db204f15767021c7a38ceba3921b48a807c16c608d21581cdaaa", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00000__wfv__glossary-comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:09:52.598 'Word found unreadable content in 00000__wfv__glossary-comments-mu-body-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-28 14:10:41.978 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__glossary-comments-mu-body...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s86b", "pass": 2, "name": "glossary-comments-mu-body-reference", "sha256": "5c97cf181c69db204f15767021c7a38ceba3921b48a807c16c608d21581cdaaa", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00000__wfv__glossary-comments-mu-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:13:18.779 \"Word found unreadable content in 00000__wfv__glossary-comments-mu-body-reference.docx. Do you want  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__glossary-comments-mu-body-reference.docx; refusing to guess"}
{"run": "s86b", "pass": 1, "name": "s86b-control-minimal", "sha256": "1fdfc93382f9fb4e67597071afa261c4b85b6e4a869fe01fa1964a83979e75ea", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:12:15+00:00", "staged": "00008__wfv__s86b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86b", "pass": 2, "name": "s86b-control-minimal", "sha256": "1fdfc93382f9fb4e67597071afa261c4b85b6e4a869fe01fa1964a83979e75ea", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:14:38+00:00", "staged": "00008__wfv__s86b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 1, "name": "footnotes-malformed-header-reference", "sha256": "8d44233267ef95a0c631d0e55abcb7202d8ed703d20973c2a4c9300a07739597", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00001__wfv__footnotes-malformed-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-malformed-header-reference_byword.pdf (16233 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 2, "name": "footnotes-malformed-header-reference", "sha256": "8d44233267ef95a0c631d0e55abcb7202d8ed703d20973c2a4c9300a07739597", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00001__wfv__footnotes-malformed-header-reference.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-malformed-header-reference_byword.pdf (16233 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 1, "name": "footnotes-malformed-body-reference", "sha256": "df977144dd0d81b6cdfc66bde5f8366c2a176c98c6fa6f513817cdf5878dd912", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00000__wfv__footnotes-malformed-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:15:07.281 \"Word found unreadable content in 00000__wfv__footnotes-malformed-body-reference.docx. Do you want t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__footnotes-malformed-body-reference.docx; refusing to guess"}
{"run": "s86c", "pass": 2, "name": "footnotes-malformed-body-reference", "sha256": "df977144dd0d81b6cdfc66bde5f8366c2a176c98c6fa6f513817cdf5878dd912", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00000__wfv__footnotes-malformed-body-reference.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:21:04.582 \"Word found unreadable content in 00000__wfv__footnotes-malformed-body-reference.docx. Do you want t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__footnotes-malformed-body-reference.docx; refusing to guess"}
{"run": "s86c", "pass": 1, "name": "header-mu-unused-fallback", "sha256": "41c624faaeb00d26d7d8bac47e88e529200cd539c65c7389c1aab09d51764dbb", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00003__wfv__header-mu-unused-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-mu-unused-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 2, "name": "header-mu-unused-fallback", "sha256": "41c624faaeb00d26d7d8bac47e88e529200cd539c65c7389c1aab09d51764dbb", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00003__wfv__header-mu-unused-fallback.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-mu-unused-fallback_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 1, "name": "header-mu-used-fallback", "sha256": "c810ce29bb589a8b0393e828079d02bd017908e5d452345909c8bf59faf69065", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00005__wfv__header-mu-used-fallback.docx", "logVerdict": "no-evidence", "tableVerdict": "other", "pdf": false, "evidence": [], "excluded": "no evidence: the driver's AppleEvent timed out", "error": "Microsoft Word got an error: AppleEvent timed out."}
{"run": "s86c", "pass": 2, "name": "header-mu-used-fallback", "sha256": "c810ce29bb589a8b0393e828079d02bd017908e5d452345909c8bf59faf69065", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00005__wfv__header-mu-used-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:22:16.503 \"Word found unreadable content in 00005__wfv__header-mu-used-fallback.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__header-mu-used-fallback.docx; refusing to guess"}
{"run": "s86c", "pass": 3, "name": "header-mu-used-fallback", "sha256": "c810ce29bb589a8b0393e828079d02bd017908e5d452345909c8bf59faf69065", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:23:31+00:00", "staged": "00000__wfv__header-mu-used-fallback.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:23:24.555 \"Word found unreadable content in 00000__wfv__header-mu-used-fallback.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__header-mu-used-fallback.docx; refusing to guess"}
{"run": "s86c", "pass": 1, "name": "header-mu-unused-choice", "sha256": "dd6c542b5aaa3d3edc81a197e1fef5b6e2bb902500c8904fa0bbe433b26b30ab", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00002__wfv__header-mu-unused-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-mu-unused-choice_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 2, "name": "header-mu-unused-choice", "sha256": "dd6c542b5aaa3d3edc81a197e1fef5b6e2bb902500c8904fa0bbe433b26b30ab", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00002__wfv__header-mu-unused-choice.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-mu-unused-choice_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 1, "name": "header-mu-used-choice", "sha256": "12495fc0640830fedb0240c976e5d7d9bca55ab76df7175b36770c87b681eb83", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00004__wfv__header-mu-used-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:15:26.063 \"Word found unreadable content in 00004__wfv__header-mu-used-choice.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__header-mu-used-choice.docx; refusing to guess"}
{"run": "s86c", "pass": 2, "name": "header-mu-used-choice", "sha256": "12495fc0640830fedb0240c976e5d7d9bca55ab76df7175b36770c87b681eb83", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00004__wfv__header-mu-used-choice.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-28 14:21:22.651 \"Word found unreadable content in 00004__wfv__header-mu-used-choice.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__header-mu-used-choice.docx; refusing to guess"}
{"run": "s86c", "pass": 1, "name": "s86c-control-minimal", "sha256": "fc4290bd6a17ce1c68f01c6171c299c7c24e74555d3ebcb9d2c0eb1f4264d526", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:20:27+00:00", "staged": "00006__wfv__s86c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s86c", "pass": 2, "name": "s86c-control-minimal", "sha256": "fc4290bd6a17ce1c68f01c6171c299c7c24e74555d3ebcb9d2c0eb1f4264d526", "validatorRevision": "ddf9a18ffec7a8e683c68d02e79a970b4da797c8", "observedAt": "2026-10-28T18:22:17+00:00", "staged": "00006__wfv__s86c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s86c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 86 builder, cross-check and section scripts</summary>

Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. The builder ran in the committed worktree, `WT` naming it.

`s86builder.mts`:

```ts
// Session 86 (2026-10-28, #1164): the placements #1155 and #1158 decide by the read model without direct Word evidence,
// on the minimal package (`tests/support/minimal-docx.ts`). Every MustUnderstand root names an unknown urn:foo, which
// Word refused in a read header and a body-referenced notes or comments part (sessions 84, 85).
// s86a, footer-held reference (#1155): a footnotes, endnotes or comments part the main document relates, its root
//   carrying MustUnderstand, its only reference in a used footer (`-mu-footer-reference`); the same part referenced from
//   the body (`-mu-body-reference`, expected refused); the footer-referenced part without MustUnderstand
//   (`-footer-reference-calibration`).
// s86b, reached glossary (#1155): the main document relates word/glossary/document.xml, whose docPartBody sectPr uses
//   word/glossary/header1.xml (session 26's glossaryRef shape). Per kind, the glossary relates a MustUnderstand part
//   whose only reference sits in that header (`glossary-<kind>s-mu-header-reference`) or in the docPartBody
//   (`-mu-body-reference`). `glossary-header-mu-used` puts MustUnderstand on the used glossary header itself: does Word
//   read the glossary's header at all?
// s86c (#1155, #1158): `footnotes-malformed-header-reference` puts an undeclared-Requires Choice (`mce-malformed`) in
//   a footnotes part whose only reference sits in a read header; `-body-reference` is its calibration. The
//   `header-mu-*-fallback` and `-choice` rows relate a MustUnderstand header through a relationship inside a selected
//   mc:Fallback, or an understood mc:Choice (Requires="w14"), of the main document's relationships part, unused or used.
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: WT=<tree> CHUNK=s86a tsx <abs path to this file>
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const MU = ` xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo"`;
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
/** `parts` with `r:` declared on the main document, `run` appended inside its only paragraph and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** `parts` plus a part related by the main document as `segment`, typed `type`. */
const withRelated = (
    parts: Record<string, string>,
    name: string,
    xml: string,
    id: string,
    segment: string,
    type: string,
    target = name,
) => ({
    ...parts,
    [`word/${name}`]: xml,
    [SIDECAR]: appendRels(parts[SIDECAR]!, relationship(id, segment, target)),
    [CT]: overrides(parts[CT]!, [`word/${name}`, type]),
});

// shared
type Story = "footnote" | "endnote" | "comment";
const TEXT_P = "<w:p><w:r><w:t>Text 86</w:t></w:r></w:p>";
const storyXml = (kind: Story, root: string) =>
    kind === "comment"
        ? `${XML_DECL}<w:comments xmlns:w="${W}"${root}><w:comment w:id="0" w:author="a">${TEXT_P}</w:comment></w:comments>`
        : `${XML_DECL}<w:${kind}s xmlns:w="${W}"${root}><w:${kind} w:id="1">${TEXT_P}</w:${kind}></w:${kind}s>`;
const storyRef = (kind: Story) =>
    kind === "comment" ? `<w:r><w:commentReference w:id="0"/></w:r>` : `<w:r><w:${kind}Reference w:id="1"/></w:r>`;
const withStory = (parts: Record<string, string>, kind: Story, xml: string) =>
    withRelated(parts, `${kind}s.xml`, xml, "rIdS", `${kind}s`, `${WML}.${kind}s+xml`);
/** `parts` with a used `segment` story (`word/<segment>1.xml`, referenced by the section) holding `run` and carrying `root` on its root. */
const withUsed = (parts: Record<string, string>, segment: "header" | "footer", run: string, root = "") => {
    const tag = segment === "header" ? "hdr" : "ftr";
    const id = segment === "header" ? "rIdH" : "rIdF";
    const xml = `${XML_DECL}<w:${tag} xmlns:w="${W}"${root}><w:p><w:r><w:t>${segment === "header" ? "Header" : "Footer"} 86</w:t></w:r>${run}</w:p></w:${tag}>`;
    return mainWith(
        withRelated(parts, `${segment}1.xml`, xml, id, segment, `${WML}.${segment}+xml`),
        "",
        `<w:${segment}Reference w:type="default" r:id="${id}"/>`,
    );
};

// s86a
const footerRows = (kind: Story): Row[] => [
    [
        `${kind}s-mu-footer-reference`,
        `#1155: word/${kind}s.xml related by the main document, root MustUnderstand urn:foo, its only reference in a used footer`,
        () => buildDocx(withUsed(withStory(P, kind, storyXml(kind, MU)), "footer", storyRef(kind))),
    ],
    [
        `${kind}s-mu-body-reference`,
        "calibration: the same part referenced from the body",
        () => buildDocx(mainWith(withStory(P, kind, storyXml(kind, MU)), storyRef(kind))),
    ],
    [
        `${kind}s-footer-reference-calibration`,
        "calibration: the footer-referenced part without MustUnderstand",
        () => buildDocx(withUsed(withStory(P, kind, storyXml(kind, "")), "footer", storyRef(kind))),
    ],
];

// s86b
const GLOSSARY_TYPE = `${WML}.document.glossary+xml`;
const glossary = (opts: { kind?: Story; bodyRun?: string; headerRun?: string; headerRoot?: string }) => {
    const { kind, bodyRun = "", headerRun = "", headerRoot = "" } = opts;
    const doc =
        `${XML_DECL}<w:glossaryDocument xmlns:w="${W}" xmlns:r="${R}"><w:docParts><w:docPart><w:docPartPr><w:name w:val="Part"/>` +
        `<w:category><w:name w:val="General"/><w:gallery w:val="placeholder"/></w:category><w:guid w:val="{6A9E2C40-3F1B-4C55-9D2E-7B1A0C9D4E86}"/></w:docPartPr>` +
        `<w:docPartBody><w:p><w:r><w:t>Part 86</w:t></w:r>${bodyRun}</w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdH"/></w:sectPr></w:docPartBody>` +
        `</w:docPart></w:docParts></w:glossaryDocument>`;
    const rels = [relationship("rIdH", "header", "header1.xml"), kind ? relationship("rIdS", `${kind}s`, `${kind}s.xml`) : ""].join("");
    const parts: Record<string, string> = {
        ...P,
        "word/glossary/document.xml": doc,
        "word/glossary/_rels/document.xml.rels": `${XML_DECL}<Relationships xmlns="${PR}">${rels}</Relationships>`,
        "word/glossary/header1.xml": `${XML_DECL}<w:hdr xmlns:w="${W}"${headerRoot}><w:p><w:r><w:t>Glossary header 86</w:t></w:r>${headerRun}</w:p></w:hdr>`,
        [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdG", "glossaryDocument", "glossary/document.xml")),
        [CT]: overrides(
            P[CT]!,
            ["word/glossary/document.xml", GLOSSARY_TYPE],
            ["word/glossary/header1.xml", `${WML}.header+xml`],
            ...(kind ? [[`word/glossary/${kind}s.xml`, `${WML}.${kind}s+xml`] as [string, string]] : []),
        ),
    };
    if (kind) parts[`word/glossary/${kind}s.xml`] = storyXml(kind, MU);
    return parts;
};
const glossaryRows = (kind: Story): Row[] => [
    [
        `glossary-${kind}s-mu-header-reference`,
        `#1155: a reached glossary relates word/glossary/${kind}s.xml, root MustUnderstand urn:foo, its only reference in the glossary's used header`,
        () => buildDocx(glossary({ kind, headerRun: storyRef(kind) })),
    ],
    [
        `glossary-${kind}s-mu-body-reference`,
        "calibration: the same part referenced from the glossary's docPartBody",
        () => buildDocx(glossary({ kind, bodyRun: storyRef(kind) })),
    ],
];

// s86c
const MALFORMED = ` xmlns:mc="${MC}"`;
const malformedFootnotes = () =>
    `${XML_DECL}<w:footnotes xmlns:w="${W}"${MALFORMED}><w:footnote w:id="1"><w:p><mc:AlternateContent><mc:Choice Requires="zz"><w:r><w:t>A</w:t></w:r></mc:Choice><mc:Fallback><w:r><w:t>B</w:t></w:r></mc:Fallback></mc:AlternateContent></w:p></w:footnote></w:footnotes>`;
const MCE_DECLS = `xmlns:mc="${MC}" xmlns:foo="urn:foo" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"`;
const liftedHeader = (shape: "fallback" | "choice", used: boolean) => {
    const xml = `${XML_DECL}<w:hdr xmlns:w="${W}"${MU}><w:p><w:r><w:t>Header 86</w:t></w:r></w:p></w:hdr>`;
    const parts = withRelated(P, "header1.xml", xml, "rIdH", "header", `${WML}.header+xml`);
    const rel = relationship("rIdH", "header", "header1.xml");
    const wrapped =
        shape === "fallback"
            ? `<mc:AlternateContent><mc:Choice Requires="foo"/><mc:Fallback>${rel}</mc:Fallback></mc:AlternateContent>`
            : `<mc:AlternateContent><mc:Choice Requires="w14">${rel}</mc:Choice><mc:Fallback/></mc:AlternateContent>`;
    parts[SIDECAR] = replaceOnce(
        replaceOnce(parts[SIDECAR]!, rel, wrapped),
        `<Relationships xmlns="${PR}">`,
        `<Relationships xmlns="${PR}" ${MCE_DECLS}>`,
    );
    return used ? mainWith(parts, "", `<w:headerReference w:type="default" r:id="rIdH"/>`) : parts;
};

type Row = [string, string, () => Promise<Uint8Array>];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s86a: withControl("s86a", [...footerRows("footnote"), ...footerRows("endnote"), ...footerRows("comment")]),
    s86b: withControl("s86b", [
        [
            "glossary-header-mu-used",
            "calibration: the reached glossary's used header with root MustUnderstand urn:foo",
            () => buildDocx(glossary({ headerRoot: MU })),
        ],
        [
            "glossary-header-calibration",
            "calibration: the reached glossary and its used header, no MustUnderstand",
            () => buildDocx(glossary({})),
        ],
        ...glossaryRows("footnote"),
        ...glossaryRows("endnote"),
        ...glossaryRows("comment"),
    ]),
    s86c: withControl("s86c", [
        [
            "footnotes-malformed-header-reference",
            "#1155: word/footnotes.xml holding an undeclared-Requires Choice, its only reference in a read header",
            () => buildDocx(withUsed(withStory(P, "footnote", malformedFootnotes()), "header", storyRef("footnote"))),
        ],
        [
            "footnotes-malformed-body-reference",
            "calibration: the same part referenced from the body",
            () => buildDocx(mainWith(withStory(P, "footnote", malformedFootnotes()), storyRef("footnote"))),
        ],
        [
            "header-mu-unused-fallback",
            "#1158: a MustUnderstand header related through a relationship inside a selected mc:Fallback, unused",
            () => buildDocx(liftedHeader("fallback", false)),
        ],
        ["header-mu-used-fallback", "calibration: the same header used", () => buildDocx(liftedHeader("fallback", true))],
        [
            "header-mu-unused-choice",
            '#1158: the header related through an understood mc:Choice (Requires="w14"), unused',
            () => buildDocx(liftedHeader("choice", false)),
        ],
        ["header-mu-used-choice", "calibration: the same header used", () => buildDocx(liftedHeader("choice", true))],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`compare.py`:

```python
"""Join the two evidenced runs of the session-86 chunks: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are its chunk's first and second passes, except where the first pass left no evidence (the driver's
AppleEvent timed out): there the row was rerun from byte-identical bytes as pass3, and its runs are pass2 and pass3.
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s86a", "s86b", "s86c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def runs_for(label, name):
    """The two evidenced runs of a row, and the run whose first pass left no evidence, if any."""
    first, second, third = ROOT / label, ROOT / label / "pass2", ROOT / label / "pass3"
    if checks(first)[name]["logVerdict"] == "no-evidence":
        assert third.exists() and name in checks(third), (label, name)
        return [second, third], first
    return [first, second], None


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    for name, spec in specs.items():
        runs, dropped = runs_for(label, name)
        for run in runs + ([dropped] if dropped else []):
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        outcome = TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown"
        all_rejected = all(r in REJECTIONS for r in readings)
        all_clean = all(r == "clean-open" for r in readings)
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "noEvidenceRun": str(dropped.relative_to(ROOT)) if dropped else None, "readings": readings,
                     "agreed": agreed, "outcome": outcome, "everyReadingRejects": all_rejected, "everyReadingClean": all_clean,
                     "wordValid": spec["wordValid"]["valid"], "control": spec["issue"] == "control",
                     "validatorMatchesWord": agreed and ((all_rejected and spec["wordValid"]["valid"] is False) or (all_clean and spec["wordValid"]["valid"] is True))})
(ROOT / "s86/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<48} {r['sha256'][:16]} outcome={r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['validatorMatchesWord']} runs={r['runs']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| validator matches Word:", sum(r["validatorMatchesWord"] for r in rows), "/", len(rows))
```

`section.py`:

`````python
"""Render the session-86 part of docs/plans/evidence/word-probes-2026-10-24.md into s86/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes, which names each row's two
evidenced runs. The validator label comes from the rows' `validatorRevision`, never from this script. The text Word
rendered is read from its own PDFs with pdftotext, so the narrative's "rendered" claims are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s86a", "s86b", "s86c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s86/results.json").read_text())}


def cell(v):
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def strict_cell(v):
    # The column names the markup-compatibility, XML-syntax and relationship findings, and counts the others.
    if v["valid"] is None:
        return cell(v)
    if v["valid"]:
        return "valid"
    probed = [e for e in v["errors"] if e.startswith(("mce-", "xml-", "rels-"))]
    rest = len(v["errors"]) - len(probed)
    named = ", ".join(f"`{e}`" for e in probed)
    if rest:
        named = f"{named}{', ' if named else ''}{rest} other finding{'s' if rest > 1 else ''}"
    return "invalid: " + named


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def run_at(run, file):
    return datetime.fromisoformat(manifest(run, file)["run_at"]).astimezone(timezone.utc)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


def record(label, n, s, run, row, t, **extra):
    out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s.get("validatorRevision"),
           "observedAt": t.isoformat(), "staged": row["staged"], "logVerdict": row["logVerdict"],
           "tableVerdict": row["outcomesVerdict"], "pdf": row["pdf"], "evidence": row["evidence"], **extra}
    error = manifest(run, s["file"]).get("error")
    if error:
        out["error"] = error
    return json.dumps(out, ensure_ascii=False)


rows, raw, starts, ends, revisions = [], [], [], [], set()
agreed = 0
for label in CHUNKS:
    specs = [json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()]
    for s in specs:
        result = results[(label, s["file"])]
        runs = [ROOT / r for r in result["runs"]]
        revisions.add(s.get("validatorRevision", "unknown"))
        times = [run_at(r, s["file"]) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        agreed += result["agreed"]
        cs = [checks(r)[s["file"]] for r in runs]
        shape = s["issue"].replace("|", "\\|")
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {shape} | `{s['sha256'][:16]}` | "
            f"{word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | {cell(s['wordValid'])} | {strict_cell(s['strict'])} |"
        )
        if result["noEvidenceRun"]:
            dropped = ROOT / result["noEvidenceRun"]
            raw.append(record(label, 1, s, dropped, checks(dropped)[s["file"]], run_at(dropped, s["file"]), excluded="no evidence: the driver's AppleEvent timed out"))
        for r, c, t in zip(runs, cs, times):
            n = {"": 1, "pass2": 2, "pass3": 3}[r.name if r.name.startswith("pass") else ""]
            raw.append(record(label, n, s, r, c, t))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
at = rev[:8]

REFUSED = {"footnotes-mu-body-reference.docx", "endnotes-mu-body-reference.docx", "comments-mu-body-reference.docx",
           "glossary-header-mu-used.docx", "glossary-footnotes-mu-body-reference.docx", "glossary-endnotes-mu-body-reference.docx",
           "glossary-comments-mu-body-reference.docx", "footnotes-malformed-body-reference.docx", "header-mu-used-fallback.docx",
           "header-mu-used-choice.docx"}
# The narrative's claims, checked against results.json: every row's four readings agree; Word offered recovery for
# exactly REFUSED and opened every other row clean; word-valid at the probed revision matches Word on every row.
for (label, file), r in results.items():
    assert r["agreed"], (label, file, r)
    if file in REFUSED:
        assert r["everyReadingRejects"] and r["outcome"] == "unreadable-content-warning", (label, file, r)
    else:
        assert set(r["readings"]) == {"clean-open"}, (label, file, r)
    assert r["validatorMatchesWord"], (label, file, r)
    assert (r["noEvidenceRun"] is not None) is (file == "header-mu-used-fallback.docx"), (label, file, r)
assert agreed == len(rows) == 26, (agreed, len(rows))
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        opened = [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()]
        assert opened == files, (run, opened)
# The text Word rendered, every run: a used main-document footer renders "Footer 86" after "Hello", a read header
# "Header 86" before it, a glossary nothing, and no row a note's or comment's "Text 86"; a refused row left no PDF.
EXPECTED = {"s86a": lambda f: "Hello" if "control" in f else "Hello Footer 86",
            "s86b": lambda f: "Hello",
            "s86c": lambda f: "Header 86 Hello" if f == "footnotes-malformed-header-reference.docx" else "Hello"}
for label in CHUNKS:
    for run in (ROOT / label, ROOT / label / "pass2", ROOT / label / "pass3"):
        if not run.exists():
            continue
        for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
            file = json.loads(line)["original_filename"]
            text = rendered(run, file)
            if file in REFUSED or (run.name == label and file == "header-mu-used-fallback.docx"):
                assert text is None, (run, file, text)
            else:
                assert text == EXPECTED[label](file), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}", (min(starts), max(ends))
matches = sum(r["validatorMatchesWord"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 86: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {at}",
    "",
    f"The placements [#1155]({I}1155) and [#1158]({I}1158) decide by the read model, which sessions 34, 84 and 85 "
    f"bracket but did not show Word ([#1164]({I}1164), review 1156 F4). Three chunks, on the minimal package. Every "
    "`mc:MustUnderstand=\"foo\"` names an unknown `urn:foo`, which Word refused in a read header and in a "
    "body-referenced notes or comments part (sessions 84 and 85).",
    "",
    f"- **s86a, [#1155]({I}1155).** A footnotes, endnotes or comments part the main document relates, with the "
    "attribute on its root, whose only reference sits in a used footer (`-mu-footer-reference`). The same part "
    "referenced from the body (`-mu-body-reference`) and the footer-referenced part without the attribute "
    "(`-footer-reference-calibration`) are calibrations.",
    f"- **s86b, [#1155]({I}1155).** The main document relates `word/glossary/document.xml`, whose docPartBody `w:sectPr` "
    "uses `word/glossary/header1.xml` (session 26's glossaryRef shape). `glossary-header-mu-used` puts the attribute on "
    "that header, to show whether Word reads it; `glossary-header-calibration` leaves it off. Per kind, the glossary "
    "relates a part with the attribute whose only reference sits in that header (`glossary-<kind>s-mu-header-reference`) "
    "or in the docPartBody (`-mu-body-reference`).",
    f"- **s86c, [#1155]({I}1155) and [#1158]({I}1158).** `footnotes-malformed-header-reference` puts an "
    "undeclared-`Requires` Choice (`mce-malformed`) in a footnotes part whose only reference sits in a read header; "
    "`-body-reference` is its calibration. The `header-mu-` rows relate a header with the attribute through a "
    "relationship inside a selected `mc:Fallback`, or an understood `mc:Choice` (`Requires=\"w14\"`), of the main "
    "document's relationships part, the header unused or referenced by the section.",
    "",
    "Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    "`wordpdf_outcomes.py`. The first s86c run left no evidence for `header-mu-used-fallback`: the driver's AppleEvent "
    "timed out. That row ran a third time from byte-identical bytes, beside the control, and its two runs below are the "
    "second and third; the raw records keep the first, marked excluded. Outcome is the manifest spelling when both runs "
    f"and both readings agree, and `unknown` otherwise; {agreed} of {len(rows)} rows agree. The two times in Observed "
    "are the ends of the row's two runs. Shape is the builder's description of the specimen. The builder recorded the "
    f"validator revision in every row (`{rev}`). The strict column names the markup-compatibility, XML-syntax and "
    "relationship findings, and counts the others.",
    "",
    "Every calibration Word was meant to open, and every control, opened clean. Every row Word opened renders the main "
    "document's `Hello` (`pdftotext`), after `Header 86` where the section uses a header and before `Footer 86` where it "
    "uses a footer. No glossary text and no note's or comment's `Text 86` renders. No refused row left a PDF.",
    "",
    "- **Word does not read a notes or comments part whose only reference is in a footer either.** It opened clean all "
    "three `-mu-footer-reference` rows, and offered to recover unreadable content for the same parts referenced from "
    "the body.",
    "- **Word reads a reached glossary's used header, and not a notes or comments part only that header references.** "
    "It offered recovery for `glossary-header-mu-used`, opened clean the three glossary `-mu-header-reference` rows, "
    "and offered recovery for the same parts referenced from the docPartBody.",
    "- **Malformed compatibility follows the same rule.** Word opened clean the undeclared-`Requires` Choice in a "
    "footnotes part only a read header references, and offered recovery for it referenced from the body.",
    "- **A relationship markup compatibility selects relates a header as a direct one does.** Word opened clean the "
    "header related through a selected Fallback or an understood Choice and unused, and offered recovery for each used.",
    "",
    f"Word-valid at {at} matches Word on {matches} of {len(rows)} rows. At 07450f03, before [#1158]({I}1158), it rejected "
    "`header-mu-unused-fallback` and `header-mu-unused-choice` (`mce-must-understand` an error in `word/header1.xml`), "
    "both of which Word opened clean.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {at} | strict at {at} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 86</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 86 builder, cross-check and section scripts</summary>",
    "",
    "Staging the second run and reading the logs used session 41's `stage_pass2.py` and `logcheck.py`, above, unchanged. "
    "The builder ran in the committed worktree, `WT` naming it.",
    "",
]
for name, path, lang in (("s86builder.mts", ROOT / "s86builder.mts", "ts"), ("compare.py", ROOT / "s86/compare.py", "python"),
                         ("section.py", ROOT / "s86/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s86/section.md").write_text("\n".join(out))
print(len(rows), "rows,", len(raw), "raw records,", agreed, "agreed,", matches, "match")
`````

</details>

### Session 87: 03:18Z–03:30Z on 2026-10-30, validator columns at eaf93885 and d589ca84

Three questions word-valid decided without Word evidence: [#776](https://github.com/jandira-tech/docx-validate/issues/776), [#1127](https://github.com/jandira-tech/docx-validate/issues/1127) and [#1136](https://github.com/jandira-tech/docx-validate/issues/1136). Five chunks, on the minimal package.

- **s87a, [#776](https://github.com/jandira-tech/docx-validate/issues/776).** `word/styles.xml` typed `…styles+xml; charset=utf-8` (s56a's spelling), also the target of a used header relationship, or of a comments, footnotes or endnotes relationship, in place of s56a's read footer (`styles-charset-<kind>-used`). The comments, footnotes and endnotes relationships are read with no body reference, so no dangling reference adds its own recovery defect. s56a's charset part alone is the calibration.
- **s87b, [#776](https://github.com/jandira-tech/docx-validate/issues/776).** Each co-reach with the exact styles type, as calibrations.
- **s87c, [#1127](https://github.com/jandira-tech/docx-validate/issues/1127).** A used header related through `ftp:header1.xml` or `httpfoo:header1.xml`, beside the stored `word/ftp:header1.xml` or `word/httpfoo:header1.xml` with an unclosed root (`-malformed-used`) or well-formed (`-wellformed-used-calibration`); the plain `header1.xml` with an unclosed root.
- **s87d, [#1127](https://github.com/jandira-tech/docx-validate/issues/1127).** The styles relationship targeting `ftp:styles.xml`, beside a stored `word/ftp:styles.xml` with an unclosed root or well-formed; the plain styles part with an unclosed root.
- **s87e, [#1136](https://github.com/jandira-tech/docx-validate/issues/1136).** s84a's `mu-stray-foo` (`word/foo.xml`, which no relationship names, with root `mc:MustUnderstand` naming an unknown `urn:foo`) beside an unclosed `word/_rels/stray.xml.rels` whose source part is not stored, or beside an unclosed sidecar of a stored `word/x.xml` nothing relates; each broken sidecar alone, and s84a's row alone, as calibrations.

Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 27 of 27 rows agree. The two times in Observed are the ends of the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at `eaf93885ca9cf46503689206e54d1e14b54cf1a8`, before the fixes; `rejudge.mts` judged the same bytes at `d589ca84610db3cda4ea44749f6d6a30ee59ae2f`.

Every control opened clean, and every PDF Word saved renders the main document's `Hello` alone (`pdftotext`). No refused row left a PDF.

- **An inexact styles type is refused over every co-reach shown.** Word offered recovery for all four s87a co-reaches and for s56a's calibration again. With the exact type it opened the comments, footnotes and endnotes co-reaches clean, and offered recovery for the header one, the exact-typed header co-reach the mismatch check already reports.
- **A target spelling a URI scheme names no part.** Word offered recovery for the used header related through `ftp:` or `httpfoo:` and for the styles part related through `ftp:`, the stored part malformed or well-formed. The plain-named malformed header drew an open error, and the plain-named malformed styles part a recovery offer.
- **Word never reads a sidecar of a part not stored, or of a part nothing relates.** It opened clean both s87e rows with an unclosed sidecar beside s84a's unread MustUnderstand part, and every calibration.

Word-valid at eaf93885 matches Word on 19 of 27 rows: it passed the six `ftp:` and `httpfoo:` rows and rejected the two broken-sidecar rows. At d589ca84 it matches on 27 of 27.

| Run    | Observed             | Specimen                                     | Shape                                                                                                                                                                  | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at eaf93885                                     | word-valid at d589ca84                                     | strict at d589ca84                                                                                                                                                                                                                                |
| ------ | -------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s87a` | 03:18:29Z, 03:25:34Z | `styles-charset-header-used`                 | #776: word/styles.xml typed application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml; charset=utf-8, also the target of a used header relationship    | `ce476532990ddda0` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`, `word-part-content-type-mismatch@word/styles.xml`                                                                                                                                      |
| `s87a` | 03:18:29Z, 03:25:34Z | `styles-charset-comments-used`               | #776: word/styles.xml typed application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml; charset=utf-8, also the target of a used comments relationship  | `16034634c739adcd` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`                                                                                                                                                                                         |
| `s87a` | 03:18:29Z, 03:25:34Z | `styles-charset-footnotes-used`              | #776: word/styles.xml typed application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml; charset=utf-8, also the target of a used footnotes relationship | `70cd755b4432175d` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`                                                                                                                                                                                         |
| `s87a` | 03:18:29Z, 03:25:34Z | `styles-charset-endnotes-used`               | #776: word/styles.xml typed application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml; charset=utf-8, also the target of a used endnotes relationship  | `7114038162924b39` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`                                                                                                                                                                                         |
| `s87a` | 03:18:29Z, 03:25:34Z | `styles-charset-alone-calibration`           | calibration (s56a): the charset-typed styles part, related only as styles                                                                                              | `f1ac5344e6028f66` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`  | invalid: `word-part-content-type-inexact@word/styles.xml`                                                                                                                                                                                         |
| `s87a` | 03:18:29Z, 03:25:34Z | `s87a-control-minimal`                       | control                                                                                                                                                                | `d2c14de55f2a4031` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87b` | 03:18:48Z, 03:25:46Z | `styles-exact-header-used-calibration`       | calibration (#776): the exact-typed styles part, also the target of a used header relationship                                                                         | `85e5ca68601f17e4` | repair-warning | repair-warning | unreadable-content-warning | invalid: `word-part-content-type-mismatch@word/styles.xml` | invalid: `word-part-content-type-mismatch@word/styles.xml` | invalid: `word-part-content-type-mismatch@word/styles.xml`                                                                                                                                                                                        |
| `s87b` | 03:18:48Z, 03:25:46Z | `styles-exact-comments-used-calibration`     | calibration (#776): the exact-typed styles part, also the target of a used comments relationship                                                                       | `955ebd34cd755af2` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87b` | 03:18:48Z, 03:25:46Z | `styles-exact-footnotes-used-calibration`    | calibration (#776): the exact-typed styles part, also the target of a used footnotes relationship                                                                      | `c7f48036ac59711c` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87b` | 03:18:48Z, 03:25:46Z | `styles-exact-endnotes-used-calibration`     | calibration (#776): the exact-typed styles part, also the target of a used endnotes relationship                                                                       | `5d1e64d0ba8226d7` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87b` | 03:18:48Z, 03:25:46Z | `s87b-control-minimal`                       | control                                                                                                                                                                | `d2c14de55f2a4031` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87c` | 03:19:42Z, 03:28:17Z | `header-ftp-malformed-used`                  | #1127: a used header related as ftp:header1.xml, stored word/ftp:header1.xml with an unclosed root                                                                     | `73148def6de84897` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `xml-syntax@word/ftp:header1.xml`, `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:header1.xml`                                                                                                                  |
| `s87c` | 03:19:42Z, 03:28:17Z | `header-httpfoo-malformed-used`              | #1127: a used header related as httpfoo:header1.xml, stored word/httpfoo:header1.xml with an unclosed root                                                             | `7ae336ff188e83d8` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `xml-syntax@word/httpfoo:header1.xml`, `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/httpfoo:header1.xml`                                                                                                          |
| `s87c` | 03:19:42Z, 03:28:17Z | `header-ftp-wellformed-used-calibration`     | calibration: the ftp:header1.xml header well-formed                                                                                                                    | `c8000841ac24be12` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:header1.xml`                                                                                                                                                     |
| `s87c` | 03:19:42Z, 03:28:17Z | `header-httpfoo-wellformed-used-calibration` | calibration: the httpfoo:header1.xml header well-formed                                                                                                                | `bbe868eb2411cfd6` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/httpfoo:header1.xml`                                                                                                                                                 |
| `s87c` | 03:19:42Z, 03:28:17Z | `header-plain-malformed-used-calibration`    | calibration: a used header related as header1.xml with an unclosed root                                                                                                | `06380daf430a3e98` | open-error     | open-error     | open-error                 | invalid: `xml-syntax@word/header1.xml`                     | invalid: `xml-syntax@word/header1.xml`                     | invalid: `xml-syntax@word/header1.xml`                                                                                                                                                                                                            |
| `s87c` | 03:19:42Z, 03:28:17Z | `s87c-control-minimal`                       | control                                                                                                                                                                | `d2c14de55f2a4031` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87d` | 03:21:42Z, 03:30:26Z | `styles-ftp-malformed`                       | #1127: the styles relationship targets ftp:styles.xml, stored word/ftp:styles.xml with an unclosed root                                                                | `3d2dfd13cd0d78fa` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `xml-syntax@word/ftp:styles.xml`, `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:styles.xml`                                                                                                                    |
| `s87d` | 03:21:42Z, 03:30:26Z | `styles-ftp-wellformed-calibration`          | calibration: the ftp:styles.xml styles part well-formed                                                                                                                | `4877a675f50e60a6` | repair-warning | repair-warning | unreadable-content-warning | valid                                                      | invalid: `rels-broken@word/_rels/document.xml.rels`        | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:styles.xml`                                                                                                                                                      |
| `s87d` | 03:21:42Z, 03:30:26Z | `styles-plain-malformed-calibration`         | calibration: the plain styles part with an unclosed root                                                                                                               | `ae093e15f3596d28` | repair-warning | repair-warning | unreadable-content-warning | invalid: `xml-syntax@word/styles.xml`                      | invalid: `xml-syntax@word/styles.xml`                      | invalid: `xml-syntax@word/styles.xml`                                                                                                                                                                                                             |
| `s87d` | 03:21:42Z, 03:30:26Z | `s87d-control-minimal`                       | control                                                                                                                                                                | `21301e980729ae10` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |
| `s87e` | 03:21:47Z, 03:30:31Z | `mu-stray-foo-broken-stray-sidecar`          | #1136: s84a's mu-stray-foo plus an unclosed word/_rels/stray.xml.rels with no source part                                                                              | `89c4393729e8a9d8` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/foo.xml`                | valid                                                      | invalid: `xml-syntax@word/_rels/stray.xml.rels`, `rels-unreferenced@word/foo.xml`, `ct-undeclared-part@word/foo.xml`, `mce-must-understand@word/foo.xml`                                                                                          |
| `s87e` | 03:21:47Z, 03:30:31Z | `mu-stray-foo-broken-existing-sidecar`       | #1136: s84a's mu-stray-foo plus an unclosed sidecar of a stored, unrelated word/x.xml                                                                                  | `9de4cea10437a77e` | clean-open     | clean-open     | clean-open                 | invalid: `mce-must-understand@word/foo.xml`                | valid                                                      | invalid: `xml-syntax@word/_rels/x.xml.rels`, `rels-unreferenced@word/foo.xml`, `rels-unreferenced@word/x.xml`, `ct-undeclared-part@word/foo.xml`, `ct-undeclared-part@word/x.xml`, `rels-id-parse@word/x.xml`, `mce-must-understand@word/foo.xml` |
| `s87e` | 03:21:47Z, 03:30:31Z | `mu-stray-foo-calibration`                   | calibration (s84a): mu-stray-foo alone                                                                                                                                 | `f5be504c78a6591f` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | invalid: `rels-unreferenced@word/foo.xml`, `ct-undeclared-part@word/foo.xml`, `mce-must-understand@word/foo.xml`                                                                                                                                  |
| `s87e` | 03:21:47Z, 03:30:31Z | `broken-stray-sidecar-calibration`           | calibration: the unclosed stray sidecar alone                                                                                                                          | `d313be3a5b1be800` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | invalid: `xml-syntax@word/_rels/stray.xml.rels`                                                                                                                                                                                                   |
| `s87e` | 03:21:47Z, 03:30:31Z | `broken-existing-sidecar-calibration`        | calibration: word/x.xml and its unclosed sidecar alone                                                                                                                 | `f79e854567fc13bb` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | invalid: `xml-syntax@word/_rels/x.xml.rels`, `rels-unreferenced@word/x.xml`, `ct-undeclared-part@word/x.xml`, `rels-id-parse@word/x.xml`                                                                                                          |
| `s87e` | 03:21:47Z, 03:30:31Z | `s87e-control-minimal`                       | control                                                                                                                                                                | `21301e980729ae10` | clean-open     | clean-open     | clean-open                 | valid                                                      | valid                                                      | valid                                                                                                                                                                                                                                             |

<details><summary>Raw records, session 87</summary>

```jsonl
{"run": "s87a", "pass": 1, "name": "styles-charset-header-used", "sha256": "ce476532990ddda0e89517eb851a6cf15c7990e04acbf67ef77a6f3cdd627cfe", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00005__wfv__styles-charset-header-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:28.547 'Word found unreadable content in 00005__wfv__styles-charset-header-used.docx. Do you want to recove … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:18:29.431 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00005__wfv__styles-charset-header-use...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 2, "name": "styles-charset-header-used", "sha256": "ce476532990ddda0e89517eb851a6cf15c7990e04acbf67ef77a6f3cdd627cfe", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00005__wfv__styles-charset-header-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:25:33.610 Microsoft Word, Word found unreadable content in 00005__wfv__styles-charset-header-used.docx. Do you … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 1, "name": "styles-charset-comments-used", "sha256": "16034634c739adcdea32a3e54a1569c542893639d2a5247d61328ade80112bb9", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00002__wfv__styles-charset-comments-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:06.887 'Word found unreadable content in 00002__wfv__styles-charset-comments-used.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:18:07.736 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__styles-charset-comments-u...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 2, "name": "styles-charset-comments-used", "sha256": "16034634c739adcdea32a3e54a1569c542893639d2a5247d61328ade80112bb9", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00002__wfv__styles-charset-comments-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:22:59.090 Microsoft Word, Word found unreadable content in 00002__wfv__styles-charset-comments-used.docx. Do y … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 1, "name": "styles-charset-footnotes-used", "sha256": "70cd755b4432175d9273933d07a84ad3b69046283d3cb6b1c19cd7fd8960a0c9", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00004__wfv__styles-charset-footnotes-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:21.329 'Word found unreadable content in 00004__wfv__styles-charset-footnotes-used.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:18:22.204 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-charset-footnotes-...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 2, "name": "styles-charset-footnotes-used", "sha256": "70cd755b4432175d9273933d07a84ad3b69046283d3cb6b1c19cd7fd8960a0c9", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00004__wfv__styles-charset-footnotes-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:24:41.719 Microsoft Word, Word found unreadable content in 00004__wfv__styles-charset-footnotes-used.docx. Do  … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 1, "name": "styles-charset-endnotes-used", "sha256": "7114038162924b39632c3ee87d6c2cf674c63f9dc94b4743be5ca1e0bcc629df", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00003__wfv__styles-charset-endnotes-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:14.099 'Word found unreadable content in 00003__wfv__styles-charset-endnotes-used.docx. Do you want to reco … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:18:14.969 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__styles-charset-endnotes-u...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 2, "name": "styles-charset-endnotes-used", "sha256": "7114038162924b39632c3ee87d6c2cf674c63f9dc94b4743be5ca1e0bcc629df", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00003__wfv__styles-charset-endnotes-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:23:51.132 Microsoft Word, Word found unreadable content in 00003__wfv__styles-charset-endnotes-used.docx. Do y … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__styles-charset-endnotes-used.docx; refusing to guess"}
{"run": "s87a", "pass": 1, "name": "styles-charset-alone-calibration", "sha256": "f1ac5344e6028f663648990f49483049a05632d74134ee668290bc96c0fe4138", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00001__wfv__styles-charset-alone-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:00.252 \"Word found unreadable content in 00001__wfv__styles-charset-alone-calibration.docx. Do you want to  … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87a", "pass": 2, "name": "styles-charset-alone-calibration", "sha256": "f1ac5344e6028f663648990f49483049a05632d74134ee668290bc96c0fe4138", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00001__wfv__styles-charset-alone-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:22:08.533 'Word found unreadable content in 00001__wfv__styles-charset-alone-calibration.docx. Do you want to  … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:22:09.103 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__styles-charset-alone-cali...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__styles-charset-alone-calibration.docx; refusing to guess"}
{"run": "s87a", "pass": 1, "name": "s87a-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:29+00:00", "staged": "00000__wfv__s87a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87a", "pass": 2, "name": "s87a-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:34+00:00", "staged": "00000__wfv__s87a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 1, "name": "styles-exact-header-used-calibration", "sha256": "85e5ca68601f17e478fc81ef1fb0222f4dfe29ca1b7930b48e095674c50b8020", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:48+00:00", "staged": "00004__wfv__styles-exact-header-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:18:47.217 'Word found unreadable content in 00004__wfv__styles-exact-header-used-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:18:48.016 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-exact-header-used-...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87b", "pass": 2, "name": "styles-exact-header-used-calibration", "sha256": "85e5ca68601f17e478fc81ef1fb0222f4dfe29ca1b7930b48e095674c50b8020", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:46+00:00", "staged": "00004__wfv__styles-exact-header-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:25:45.801 'Word found unreadable content in 00004__wfv__styles-exact-header-used-calibration.docx. Do you want … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:25:46.388 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00004__wfv__styles-exact-header-used-...)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__styles-exact-header-used-calibration.docx; refusing to guess"}
{"run": "s87b", "pass": 1, "name": "styles-exact-comments-used-calibration", "sha256": "955ebd34cd755af2770963e51b0cff6af39e8f994534f748b4d47b9e040d6063", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:48+00:00", "staged": "00001__wfv__styles-exact-comments-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-comments-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 2, "name": "styles-exact-comments-used-calibration", "sha256": "955ebd34cd755af2770963e51b0cff6af39e8f994534f748b4d47b9e040d6063", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:46+00:00", "staged": "00001__wfv__styles-exact-comments-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-comments-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 1, "name": "styles-exact-footnotes-used-calibration", "sha256": "c7f48036ac59711c4759ad29f22f2816520ad5d7ee1ff8fb18d3814968dc9e3c", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:48+00:00", "staged": "00003__wfv__styles-exact-footnotes-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-footnotes-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 2, "name": "styles-exact-footnotes-used-calibration", "sha256": "c7f48036ac59711c4759ad29f22f2816520ad5d7ee1ff8fb18d3814968dc9e3c", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:46+00:00", "staged": "00003__wfv__styles-exact-footnotes-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-footnotes-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 1, "name": "styles-exact-endnotes-used-calibration", "sha256": "5d1e64d0ba8226d7cb31ecc29bbef7e1613c800b666323ef71c954ecf36770b1", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:48+00:00", "staged": "00002__wfv__styles-exact-endnotes-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-endnotes-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 2, "name": "styles-exact-endnotes-used-calibration", "sha256": "5d1e64d0ba8226d7cb31ecc29bbef7e1613c800b666323ef71c954ecf36770b1", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:46+00:00", "staged": "00002__wfv__styles-exact-endnotes-used-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF styles-exact-endnotes-used-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 1, "name": "s87b-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:18:48+00:00", "staged": "00000__wfv__s87b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87b", "pass": 2, "name": "s87b-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:25:46+00:00", "staged": "00000__wfv__s87b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87c", "pass": 1, "name": "header-ftp-malformed-used", "sha256": "73148def6de84897d710ee72b25b760728abe8d566cafd4c5a1489a9eafdfc8d", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00000__wfv__header-ftp-malformed-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:19:00.617 'Word found unreadable content in 00000__wfv__header-ftp-malformed-used.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:19:01.418 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header-ftp-malformed-used...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 2, "name": "header-ftp-malformed-used", "sha256": "73148def6de84897d710ee72b25b760728abe8d566cafd4c5a1489a9eafdfc8d", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00000__wfv__header-ftp-malformed-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:26:01.334 'Word found unreadable content in 00000__wfv__header-ftp-malformed-used.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:26:01.882 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header-ftp-malformed-used...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 1, "name": "header-httpfoo-malformed-used", "sha256": "7ae336ff188e83d81f693149fcf2f2999d59b2beec99440e93db5c6dffbc470e", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00002__wfv__header-httpfoo-malformed-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:19:15.028 'Word found unreadable content in 00002__wfv__header-httpfoo-malformed-used.docx. Do you want to rec … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:19:15.827 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00002__wfv__header-httpfoo-malformed-...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 2, "name": "header-httpfoo-malformed-used", "sha256": "7ae336ff188e83d81f693149fcf2f2999d59b2beec99440e93db5c6dffbc470e", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00002__wfv__header-httpfoo-malformed-used.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:27:42.258 Microsoft Word, Word found unreadable content in 00002__wfv__header-httpfoo-malformed-used.docx. Do  … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 1, "name": "header-ftp-wellformed-used-calibration", "sha256": "c8000841ac24be12c1f14a58d93168726fe4648ff0476b35d07fc7ea2429cd5d", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00001__wfv__header-ftp-wellformed-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:19:07.809 'Word found unreadable content in 00001__wfv__header-ftp-wellformed-used-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:19:08.583 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__header-ftp-wellformed-use...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 2, "name": "header-ftp-wellformed-used-calibration", "sha256": "c8000841ac24be12c1f14a58d93168726fe4648ff0476b35d07fc7ea2429cd5d", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00001__wfv__header-ftp-wellformed-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:26:52.248 \"Word found unreadable content in 00001__wfv__header-ftp-wellformed-used-calibration.docx. Do you wa … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 1, "name": "header-httpfoo-wellformed-used-calibration", "sha256": "bbe868eb2411cfd60cc930e8fecea2b23e6a4690ede235ace798ab8f80c382f4", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00003__wfv__header-httpfoo-wellformed-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:19:22.213 'Word found unreadable content in 00003__wfv__header-httpfoo-wellformed-used-calibration.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:19:23.017 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-httpfoo-wellformed...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 2, "name": "header-httpfoo-wellformed-used-calibration", "sha256": "bbe868eb2411cfd60cc930e8fecea2b23e6a4690ede235ace798ab8f80c382f4", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00003__wfv__header-httpfoo-wellformed-used-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:27:50.967 'Word found unreadable content in 00003__wfv__header-httpfoo-wellformed-used-calibration.docx. Do yo … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:27:51.509 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__header-httpfoo-wellformed...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s87c", "pass": 1, "name": "header-plain-malformed-used-calibration", "sha256": "06380daf430a3e98642b606d3257cf2a57c1f65cfa7796f9ada1bbd25916d391", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00004__wfv__header-plain-malformed-used-calibration.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-29 23:19:29.415 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__header-plain-malformed-us...)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__header-plain-malformed-used-calibration.docx; refusing to guess"}
{"run": "s87c", "pass": 2, "name": "header-plain-malformed-used-calibration", "sha256": "06380daf430a3e98642b606d3257cf2a57c1f65cfa7796f9ada1bbd25916d391", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00004__wfv__header-plain-malformed-used-calibration.docx", "logVerdict": "open-error", "tableVerdict": "open-error", "pdf": false, "evidence": ["2026-10-29 23:27:58.189 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … converter.\\n(00004__wfv__header-plain-malformed-us...)'"], "error": "Word could not load it in 2 passes: open produced 0 new documents, none named 00004__wfv__header-plain-malformed-used-calibration.docx; refusing to guess"}
{"run": "s87c", "pass": 1, "name": "s87c-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:19:42+00:00", "staged": "00005__wfv__s87c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87c", "pass": 2, "name": "s87c-control-minimal", "sha256": "d2c14de55f2a40310fbe14d150285f5a7a6950aa4d841eb543f4a33000336a83", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:28:17+00:00", "staged": "00005__wfv__s87c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87d", "pass": 1, "name": "styles-ftp-malformed", "sha256": "3d2dfd13cd0d78fae9f7bbbf213e69f68a0721491755683399753d9c643f3220", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:42+00:00", "staged": "00001__wfv__styles-ftp-malformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:19:59.367 'Word found unreadable content in 00001__wfv__styles-ftp-malformed.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:20:00.251 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ery converter. (00001__wfv__styles-ftp-malformed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__styles-ftp-malformed.docx; refusing to guess"}
{"run": "s87d", "pass": 2, "name": "styles-ftp-malformed", "sha256": "3d2dfd13cd0d78fae9f7bbbf213e69f68a0721491755683399753d9c643f3220", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:26+00:00", "staged": "00001__wfv__styles-ftp-malformed.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:28:34.104 'Word found unreadable content in 00001__wfv__styles-ftp-malformed.docx. Do you want to recover the  … ? If you trust the source of this document, click Yes.'", "2026-10-29 23:28:34.972 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ery converter. (00001__wfv__styles-ftp-malformed.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00001__wfv__styles-ftp-malformed.docx; refusing to guess"}
{"run": "s87d", "pass": 1, "name": "styles-ftp-wellformed-calibration", "sha256": "4877a675f50e60a6b8519787f6f8ba63278ec08d988a925691c3b48fe31a56d7", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:42+00:00", "staged": "00002__wfv__styles-ftp-wellformed-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:20:49.964 Microsoft Word, Word found unreadable content in 00002__wfv__styles-ftp-wellformed-calibration.docx. … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87d", "pass": 2, "name": "styles-ftp-wellformed-calibration", "sha256": "4877a675f50e60a6b8519787f6f8ba63278ec08d988a925691c3b48fe31a56d7", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:26+00:00", "staged": "00002__wfv__styles-ftp-wellformed-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:29:24.695 Microsoft Word, Word found unreadable content in 00002__wfv__styles-ftp-wellformed-calibration.docx. … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87d", "pass": 1, "name": "styles-plain-malformed-calibration", "sha256": "ae093e15f3596d28d6e02481301631e9de2369bf0c463305b04a3da166290d7f", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:42+00:00", "staged": "00003__wfv__styles-plain-malformed-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:21:41.892 Microsoft Word, Word found unreadable content in 00003__wfv__styles-plain-malformed-calibration.docx … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__styles-plain-malformed-calibration.docx; refusing to guess"}
{"run": "s87d", "pass": 2, "name": "styles-plain-malformed-calibration", "sha256": "ae093e15f3596d28d6e02481301631e9de2369bf0c463305b04a3da166290d7f", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:26+00:00", "staged": "00003__wfv__styles-plain-malformed-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-29 23:30:18.312 Microsoft Word, Word found unreadable content in 00003__wfv__styles-plain-malformed-calibration.docx … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it"}
{"run": "s87d", "pass": 1, "name": "s87d-control-minimal", "sha256": "21301e980729ae10c120dbf2425eb36d47276f6cb8dcf849457b8590bb7a2d44", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:42+00:00", "staged": "00000__wfv__s87d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87d", "pass": 2, "name": "s87d-control-minimal", "sha256": "21301e980729ae10c120dbf2425eb36d47276f6cb8dcf849457b8590bb7a2d44", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:26+00:00", "staged": "00000__wfv__s87d-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87d-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "mu-stray-foo-broken-stray-sidecar", "sha256": "89c4393729e8a9d8b9a32b547c49ebdff9c5c3f24742e357d2e45c58206ef7f4", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00003__wfv__mu-stray-foo-broken-stray-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-stray-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "mu-stray-foo-broken-stray-sidecar", "sha256": "89c4393729e8a9d8b9a32b547c49ebdff9c5c3f24742e357d2e45c58206ef7f4", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00003__wfv__mu-stray-foo-broken-stray-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-stray-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "mu-stray-foo-broken-existing-sidecar", "sha256": "9de4cea10437a77e975a1fe397d2b41fee782ba4e641e7c3945d46caa59d66a1", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00002__wfv__mu-stray-foo-broken-existing-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-existing-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "mu-stray-foo-broken-existing-sidecar", "sha256": "9de4cea10437a77e975a1fe397d2b41fee782ba4e641e7c3945d46caa59d66a1", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00002__wfv__mu-stray-foo-broken-existing-sidecar.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-broken-existing-sidecar_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "mu-stray-foo-calibration", "sha256": "f5be504c78a6591fc458097a9cea2e3b603dee324d1ea1ae3488c7093f966a27", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00004__wfv__mu-stray-foo-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "mu-stray-foo-calibration", "sha256": "f5be504c78a6591fc458097a9cea2e3b603dee324d1ea1ae3488c7093f966a27", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00004__wfv__mu-stray-foo-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF mu-stray-foo-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "broken-stray-sidecar-calibration", "sha256": "d313be3a5b1be800b9e4947b2660634548273a2526bd9d3a5ef2f29b251e5c11", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00001__wfv__broken-stray-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-stray-sidecar-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "broken-stray-sidecar-calibration", "sha256": "d313be3a5b1be800b9e4947b2660634548273a2526bd9d3a5ef2f29b251e5c11", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00001__wfv__broken-stray-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-stray-sidecar-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "broken-existing-sidecar-calibration", "sha256": "f79e854567fc13bb70d1b30fa408a5b26f7ffe4441608029a875a9c04c7ee87a", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00000__wfv__broken-existing-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-existing-sidecar-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "broken-existing-sidecar-calibration", "sha256": "f79e854567fc13bb70d1b30fa408a5b26f7ffe4441608029a875a9c04c7ee87a", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00000__wfv__broken-existing-sidecar-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF broken-existing-sidecar-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 1, "name": "s87e-control-minimal", "sha256": "21301e980729ae10c120dbf2425eb36d47276f6cb8dcf849457b8590bb7a2d44", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:21:47+00:00", "staged": "00005__wfv__s87e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s87e", "pass": 2, "name": "s87e-control-minimal", "sha256": "21301e980729ae10c120dbf2425eb36d47276f6cb8dcf849457b8590bb7a2d44", "validatorRevision": "eaf93885ca9cf46503689206e54d1e14b54cf1a8", "observedAt": "2026-10-30T03:30:31+00:00", "staged": "00005__wfv__s87e-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s87e-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 87 builder, re-judge, cross-check and section scripts</summary>

Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder and the re-judge ran in the committed worktree, `WT` naming it.

`s87builder.mts`:

```ts
// Session 87 (2026-10-30): three questions word-valid decides without direct Word evidence, on the minimal package
// (`tests/support/minimal-docx.ts`).
// s87a (#776): word/styles.xml typed `…styles+xml; charset=utf-8` (s56a's inexact spelling) and also the target of a
//   used header, comments, footnotes or endnotes relationship (`styles-charset-<kind>-used`); s56a's charset styles
//   part alone (`styles-charset-alone-calibration`).
// s87b (#776): each co-reach with the exact styles type (`styles-exact-<kind>-used-calibration`).
// s87c (#1127): a used header related through a scheme-like internal target, `ftp:header1.xml` or
//   `httpfoo:header1.xml`, beside a stored word/ftp:header1.xml or word/httpfoo:header1.xml with an unclosed root
//   (`header-<scheme>-malformed-used`); the same part well-formed (`-wellformed-used-calibration`); the plain
//   `header1.xml` with an unclosed root (`header-plain-malformed-used-calibration`).
// s87d (#1127): the styles relationship's target spelled `ftp:styles.xml`, beside a stored word/ftp:styles.xml with an
//   unclosed root (`styles-ftp-malformed`); the same part well-formed (`styles-ftp-wellformed-calibration`); the plain
//   styles part with an unclosed root (`styles-plain-malformed-calibration`).
// s87e (#1136): s84a's `mu-stray-foo` (word/foo.xml, no relationship names it, root MustUnderstand urn:foo) beside an
//   unclosed word/_rels/stray.xml.rels whose source part does not exist (`mu-stray-foo-broken-stray-sidecar`), or
//   beside an unclosed sidecar of a stored, unrelated word/x.xml (`mu-stray-foo-broken-existing-sidecar`); each broken
//   sidecar alone, and s84a's row alone, as calibrations.
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: WT=<tree> CHUNK=s87a tsx <abs path to this file>
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const STYLES = `${WML}.styles+xml`;
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const PR = "http://schemas.openxmlformats.org/package/2006/relationships";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
/** `parts` with `r:` declared on the main document, `run` appended inside its only paragraph and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string>, run: string, sect = ""): Record<string, string> => ({
    ...parts,
    [MAIN]: replaceOnce(
        replaceOnce(replaceOnce(parts[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
        "</w:r></w:p>",
        `</w:r>${run}</w:p>`,
    ),
});
/** The styles part's Override (or an added one) set to `type`. */
const stylesTyped = (parts: Record<string, string>, type: string): Record<string, string> => {
    const ct = parts[CT]!;
    const existing = /<Override PartName="\/word\/styles\.xml" ContentType="[^"]*"\/>/;
    return {
        ...parts,
        [CT]: existing.test(ct)
            ? ct.replace(existing, `<Override PartName="/word/styles.xml" ContentType="${type}"/>`)
            : overrides(ct, ["word/styles.xml", type]),
    };
};

// s87a / s87b. Comments, footnotes and endnotes relationships are read with no body reference (eager); a dangling
// reference would add its own recovery defect, so only the header is referenced.
type CoReach = "header" | "comments" | "footnotes" | "endnotes";
const CO_REACH: Record<CoReach, { id: string; sect: string; run: string }> = {
    header: { id: "rIdH", sect: `<w:headerReference w:type="default" r:id="rIdH"/>`, run: "" },
    comments: { id: "rIdC", sect: "", run: "" },
    footnotes: { id: "rIdN", sect: "", run: "" },
    endnotes: { id: "rIdE", sect: "", run: "" },
};
const coReach = (type: string, kind: CoReach) => {
    const { id, sect, run } = CO_REACH[kind];
    const parts = stylesTyped(P, type);
    return mainWith(
        { ...parts, [SIDECAR]: appendRels(parts[SIDECAR]!, relationship(id, kind === "header" ? "header" : kind, "styles.xml")) },
        run,
        sect,
    );
};
const KINDS: CoReach[] = ["header", "comments", "footnotes", "endnotes"];

// s87c / s87d
const UNCLOSED_HEADER = `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header 87</w:t></w:r></w:p>`;
const HEADER = `${UNCLOSED_HEADER}</w:hdr>`;
const usedHeader = (target: string, stored: string, xml: string) =>
    mainWith(
        {
            ...P,
            [`word/${stored}`]: xml,
            [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", target)),
            [CT]: overrides(P[CT]!, [`word/${stored}`, `${WML}.header+xml`]),
        },
        "",
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );
const STYLES_XML = P["word/styles.xml"]!;
const UNCLOSED_STYLES = replaceOnce(STYLES_XML, "</w:styles>", "");
const stylesAt = (target: string, xml: string) => {
    if (target === "styles.xml") return { ...P, "word/styles.xml": xml };
    const parts: Record<string, string> = { ...P, [`word/${target}`]: xml };
    delete parts["word/styles.xml"];
    parts[SIDECAR] = replaceOnce(P[SIDECAR]!, 'Target="styles.xml"', `Target="${target}"`);
    parts[CT] = P[CT]!.includes('PartName="/word/styles.xml"')
        ? replaceOnce(P[CT]!, 'PartName="/word/styles.xml"', `PartName="/word/${target}"`)
        : overrides(P[CT]!, [`word/${target}`, STYLES]);
    return parts;
};

// s87e
const MU_FOO = `${XML_DECL}<w:document xmlns:w="${W}" xmlns:mc="${MC}" xmlns:foo="urn:foo" mc:MustUnderstand="foo"><w:body/></w:document>`;
const UNCLOSED_RELS = `${XML_DECL}<Relationships xmlns="${PR}"><Relationship`;
const X_XML = `${XML_DECL}<w:document xmlns:w="${W}"><w:body/></w:document>`;
const stray = (opts: { foo: boolean; broken?: "stray" | "existing" }) => {
    const parts: Record<string, string> = { ...P };
    if (opts.foo) parts["word/foo.xml"] = MU_FOO;
    if (opts.broken === "stray") parts["word/_rels/stray.xml.rels"] = UNCLOSED_RELS;
    if (opts.broken === "existing") {
        parts["word/x.xml"] = X_XML;
        parts["word/_rels/x.xml.rels"] = UNCLOSED_RELS;
    }
    return parts;
};

type Row = [string, string, () => Promise<Uint8Array>];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s87a: withControl("s87a", [
        ...KINDS.map((kind): Row => [
            `styles-charset-${kind}-used`,
            `#776: word/styles.xml typed ${STYLES}; charset=utf-8, also the target of a used ${kind} relationship`,
            () => buildDocx(coReach(`${STYLES}; charset=utf-8`, kind)),
        ]),
        [
            "styles-charset-alone-calibration",
            "calibration (s56a): the charset-typed styles part, related only as styles",
            () => buildDocx(stylesTyped(P, `${STYLES}; charset=utf-8`)),
        ],
    ]),
    s87b: withControl(
        "s87b",
        KINDS.map((kind): Row => [
            `styles-exact-${kind}-used-calibration`,
            `calibration (#776): the exact-typed styles part, also the target of a used ${kind} relationship`,
            () => buildDocx(coReach(STYLES, kind)),
        ]),
    ),
    s87c: withControl("s87c", [
        [
            "header-ftp-malformed-used",
            "#1127: a used header related as ftp:header1.xml, stored word/ftp:header1.xml with an unclosed root",
            () => buildDocx(usedHeader("ftp:header1.xml", "ftp:header1.xml", UNCLOSED_HEADER)),
        ],
        [
            "header-httpfoo-malformed-used",
            "#1127: a used header related as httpfoo:header1.xml, stored word/httpfoo:header1.xml with an unclosed root",
            () => buildDocx(usedHeader("httpfoo:header1.xml", "httpfoo:header1.xml", UNCLOSED_HEADER)),
        ],
        [
            "header-ftp-wellformed-used-calibration",
            "calibration: the ftp:header1.xml header well-formed",
            () => buildDocx(usedHeader("ftp:header1.xml", "ftp:header1.xml", HEADER)),
        ],
        [
            "header-httpfoo-wellformed-used-calibration",
            "calibration: the httpfoo:header1.xml header well-formed",
            () => buildDocx(usedHeader("httpfoo:header1.xml", "httpfoo:header1.xml", HEADER)),
        ],
        [
            "header-plain-malformed-used-calibration",
            "calibration: a used header related as header1.xml with an unclosed root",
            () => buildDocx(usedHeader("header1.xml", "header1.xml", UNCLOSED_HEADER)),
        ],
    ]),
    s87d: withControl("s87d", [
        [
            "styles-ftp-malformed",
            "#1127: the styles relationship targets ftp:styles.xml, stored word/ftp:styles.xml with an unclosed root",
            () => buildDocx(stylesAt("ftp:styles.xml", UNCLOSED_STYLES)),
        ],
        [
            "styles-ftp-wellformed-calibration",
            "calibration: the ftp:styles.xml styles part well-formed",
            () => buildDocx(stylesAt("ftp:styles.xml", STYLES_XML)),
        ],
        [
            "styles-plain-malformed-calibration",
            "calibration: the plain styles part with an unclosed root",
            () => buildDocx(stylesAt("styles.xml", UNCLOSED_STYLES)),
        ],
    ]),
    s87e: withControl("s87e", [
        [
            "mu-stray-foo-broken-stray-sidecar",
            "#1136: s84a's mu-stray-foo plus an unclosed word/_rels/stray.xml.rels with no source part",
            () => buildDocx(stray({ foo: true, broken: "stray" })),
        ],
        [
            "mu-stray-foo-broken-existing-sidecar",
            "#1136: s84a's mu-stray-foo plus an unclosed sidecar of a stored, unrelated word/x.xml",
            () => buildDocx(stray({ foo: true, broken: "existing" })),
        ],
        ["mu-stray-foo-calibration", "calibration (s84a): mu-stray-foo alone", () => buildDocx(stray({ foo: true }))],
        [
            "broken-stray-sidecar-calibration",
            "calibration: the unclosed stray sidecar alone",
            () => buildDocx(stray({ foo: false, broken: "stray" })),
        ],
        [
            "broken-existing-sidecar-calibration",
            "calibration: word/x.xml and its unclosed sidecar alone",
            () => buildDocx(stray({ foo: false, broken: "existing" })),
        ],
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} strict=${row.strict.valid}`,
    );
}
```

`rejudge.mts`:

```ts
// Judge the bytes session 87 showed Word (each chunk's src/) with the validator in WT, and record its revision per row.
// Run: WT=<tree> tsx <abs path to this file>
import { execFileSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(path.dirname(new URL(import.meta.url).pathname));
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const verdict = async (file: string, profile: "word-valid" | "strict") => {
    const r = await validate(file, { profile });
    return {
        valid: r.valid,
        errors: [
            ...new Set(
                r.issues
                    .filter((x: { severity: string }) => x.severity === "error")
                    .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
            ),
        ],
    };
};
const out: string[] = [];
for (const chunk of ["s87a", "s87b", "s87c", "s87d", "s87e"]) {
    for (const line of readFileSync(path.join(ROOT, chunk, "specimens.jsonl"), "utf8")
        .trim()
        .split("\n")) {
        const spec = JSON.parse(line);
        const file = path.join(ROOT, chunk, "src", spec.file);
        out.push(
            JSON.stringify({
                chunk,
                file: spec.file,
                validatorRevision: REVISION,
                wordValid: await verdict(file, "word-valid"),
                strict: await verdict(file, "strict"),
            }),
        );
    }
}
writeFileSync(path.join(ROOT, "s87", "rejudge.jsonl"), out.join("\n") + "\n");
console.log(out.length, "rows at", REVISION);
```

`compare.py`:

```python
"""Join the two runs of the session-87 chunks: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are its chunk's first pass (the chunk folder) and second pass (`pass2`), separate driver runs of
byte-identical copies. The validator verdicts come from the builder (`specimens.jsonl`, judged before the fixes) and
from `rejudge.jsonl` (the same bytes judged at the branch head).
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s87a", "s87b", "s87c", "s87d", "s87e")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s87/rejudge.jsonl").read_text().splitlines())}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def matches(readings, valid):
    return (all(r in REJECTIONS for r in readings) and valid is False) or (all(r == "clean-open" for r in readings) and valid is True)


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    runs = [ROOT / label, ROOT / label / "pass2"]
    for name, spec in specs.items():
        for run in runs:
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        at_head = head[(label, name)]
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "readings": readings, "agreed": agreed, "outcome": TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown",
                     "wordValidBefore": spec["wordValid"]["valid"], "wordValidHead": at_head["wordValid"]["valid"],
                     "headRevision": at_head["validatorRevision"],
                     "matchesBefore": agreed and matches(readings, spec["wordValid"]["valid"]),
                     "matchesHead": agreed and matches(readings, at_head["wordValid"]["valid"])})
(ROOT / "s87/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<48} {r['outcome']:<27} before={r['wordValidBefore']!s:<5} head={r['wordValidHead']!s:<5} match={r['matchesBefore']}/{r['matchesHead']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| matches before:", sum(r["matchesBefore"] for r in rows),
      "| at head:", sum(r["matchesHead"] for r in rows))
```

`section.py`:

`````python
"""Render the session-87 part of docs/plans/evidence/word-probes-2026-10-24.md into s87/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, rejudge.jsonl (the same bytes judged at the branch head) and the
results.json compare.py writes. Revisions come from the rows, never from this script. The text Word rendered is read
from its own PDFs with pdftotext, so the narrative's "rendered" claim is checked here. The PDF paths the manifests
record name the run folders before they moved into the chunk layout (`run1` is the chunk, `run2` its `pass2`); a
symbolic link at each old name keeps them readable.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s87a", "s87b", "s87c", "s87d", "s87e")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s87/results.json").read_text())}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s87/rejudge.jsonl").read_text().splitlines())}


def cell(v):
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, before, after = [], [], [], [], set(), set()
for label in CHUNKS:
    for s in map(json.loads, (ROOT / label / "specimens.jsonl").read_text().splitlines()):
        result, h = results[(label, s["file"])], head[(label, s["file"])]
        runs = [ROOT / label, ROOT / label / "pass2"]
        before.add(s["validatorRevision"])
        after.add(h["validatorRevision"])
        times = [datetime.fromisoformat(manifest(r, s["file"])["run_at"]).astimezone(timezone.utc) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        cs = [checks(r)[s["file"]] for r in runs]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {s['issue'].replace('|', chr(92) + '|')} | "
            f"`{s['sha256'][:16]}` | {word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | {cell(s['wordValid'])} | "
            f"{cell(h['wordValid'])} | {cell(h['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, cs, times), start=1):
            out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s["validatorRevision"],
                   "observedAt": t.isoformat(), "staged": c["staged"], "logVerdict": c["logVerdict"], "tableVerdict": c["outcomesVerdict"],
                   "pdf": c["pdf"], "evidence": c["evidence"]}
            if manifest(r, s["file"]).get("error"):
                out["error"] = manifest(r, s["file"])["error"]
            raw.append(json.dumps(out, ensure_ascii=False))

assert len(before) == 1 and len(after) == 1, (before, after)
b, a = next(iter(before))[:8], next(iter(after))[:8]
OPEN_ERROR = {"header-plain-malformed-used-calibration.docx"}
CLEAN = {"s87b": {"styles-exact-comments-used-calibration.docx", "styles-exact-footnotes-used-calibration.docx",
                  "styles-exact-endnotes-used-calibration.docx"}}
# The narrative's claims, checked against results.json: every row's four readings agree; Word opened clean exactly the
# controls, the three exact-typed s87b co-reaches and every s87e row, refused the plain malformed header with an open
# error, and offered recovery for every other row; word-valid at the head matches Word on every row, and before the
# fixes it missed exactly the six s87c/s87d scheme rows and the two s87e sidecar rows.
for (label, file), r in results.items():
    assert r["agreed"], (label, file)
    clean = "control" in file or label == "s87e" or file in CLEAN.get(label, set())
    want = "clean-open" if clean else "open-error" if file in OPEN_ERROR else "unreadable-content-warning"
    assert r["outcome"] == want, (label, file, r["outcome"], want)
    assert r["matchesHead"], (label, file)
    missed = (label in ("s87c", "s87d") and ("ftp" in file or "httpfoo" in file)) or file.startswith("mu-stray-foo-broken")
    assert r["matchesBefore"] is not missed, (label, file)
# The driver opens files in name order (#671), and every PDF Word saved renders the main document's "Hello" alone.
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        assert [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()] == files, run
        for file in files:
            text = rendered(run, file)
            assert (text is None) is (results[(label, file)]["outcome"] != "clean-open"), (run, file)
            assert text in (None, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}"
n = len(rows)
mb, ma = sum(r["matchesBefore"] for r in results.values()), sum(r["matchesHead"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 87: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {b} and {a}",
    "",
    f"Three questions word-valid decided without Word evidence: [#776]({I}776), [#1127]({I}1127) and [#1136]({I}1136). "
    "Five chunks, on the minimal package.",
    "",
    f"- **s87a, [#776]({I}776).** `word/styles.xml` typed `…styles+xml; charset=utf-8` (s56a's spelling), also the target "
    "of a used header relationship, or of a comments, footnotes or endnotes relationship, in place of s56a's read footer "
    "(`styles-charset-<kind>-used`). The comments, footnotes and endnotes relationships are read with no body reference, so "
    "no dangling reference adds its own recovery defect. s56a's charset part alone is the calibration.",
    f"- **s87b, [#776]({I}776).** Each co-reach with the exact styles type, as calibrations.",
    f"- **s87c, [#1127]({I}1127).** A used header related through `ftp:header1.xml` or `httpfoo:header1.xml`, beside the "
    "stored `word/ftp:header1.xml` or `word/httpfoo:header1.xml` with an unclosed root (`-malformed-used`) or well-formed "
    "(`-wellformed-used-calibration`); the plain `header1.xml` with an unclosed root.",
    f"- **s87d, [#1127]({I}1127).** The styles relationship targeting `ftp:styles.xml`, beside a stored "
    "`word/ftp:styles.xml` with an unclosed root or well-formed; the plain styles part with an unclosed root.",
    f"- **s87e, [#1136]({I}1136).** s84a's `mu-stray-foo` (`word/foo.xml`, which no relationship names, with root "
    "`mc:MustUnderstand` naming an unknown `urn:foo`) beside an unclosed `word/_rels/stray.xml.rels` whose source part is "
    "not stored, or beside an unclosed sidecar of a stored `word/x.xml` nothing relates; each broken sidecar alone, and "
    "s84a's row alone, as calibrations.",
    "",
    "Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    f"`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {sum(r['agreed'] for r in results.values())} of {n} rows agree. The two times in Observed are the ends of "
    "the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at "
    f"`{next(iter(before))}`, before the fixes; `rejudge.mts` judged the same bytes at `{next(iter(after))}`.",
    "",
    "Every control opened clean, and every PDF Word saved renders the main document's `Hello` alone (`pdftotext`). No "
    "refused row left a PDF.",
    "",
    "- **An inexact styles type is refused over every co-reach shown.** Word offered recovery for all four s87a co-reaches "
    "and for s56a's calibration again. With the exact type it opened the comments, footnotes and endnotes co-reaches clean, "
    "and offered recovery for the header one, the exact-typed header co-reach the mismatch check already reports.",
    "- **A target spelling a URI scheme names no part.** Word offered recovery for the used header related through "
    "`ftp:` or `httpfoo:` and for the styles part related through `ftp:`, the stored part malformed or well-formed. The "
    "plain-named malformed header drew an open error, and the plain-named malformed styles part a recovery offer.",
    "- **Word never reads a sidecar of a part not stored, or of a part nothing relates.** It opened clean both s87e rows "
    "with an unclosed sidecar beside s84a's unread MustUnderstand part, and every calibration.",
    "",
    f"Word-valid at {b} matches Word on {mb} of {n} rows: it passed the six `ftp:` and `httpfoo:` rows and rejected the two "
    f"broken-sidecar rows. At {a} it matches on {ma} of {n}.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {b} | word-valid at {a} | strict at {a} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 87</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 87 builder, re-judge, cross-check and section scripts</summary>",
    "",
    "Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder and the re-judge ran in the committed "
    "worktree, `WT` naming it.",
    "",
]
for name, path, lang in (("s87builder.mts", ROOT / "s87builder.mts", "ts"), ("rejudge.mts", ROOT / "s87/rejudge.mts", "ts"),
                         ("compare.py", ROOT / "s87/compare.py", "python"), ("section.py", ROOT / "s87/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s87/section.md").write_text("\n".join(out))
print(n, "rows,", len(raw), "raw records,", mb, "/", ma, "match")
`````

</details>

### Session 88: 17:59Z–18:09Z on 2026-10-30, validator columns at 45e7962f and 8bfa4ea0

The placements of a scheme-like internal target session 87 did not show Word ([#1178](https://github.com/jandira-tech/docx-validate/issues/1178), the follow-up to [#1127](https://github.com/jandira-tech/docx-validate/issues/1127)). Session 87 offered recovery for a used header and the styles part related through `ftp:` beside the well-formed `word/ftp:…` part the path spells, so every row here stores that part well-formed, and each placement has a calibration through its plain name. Three chunks, on the minimal package.

- **s88a.** A header the main document relates through `ftp:header1.xml` that no `w:headerReference` uses; a `_rels/.rels` styles relationship through `ftp:styles.xml`, stored `/ftp:styles.xml`, with the main document's own styles relationship intact; an unused image related through `ftp:image1.png`.
- **s88b.** The main document's settings, numbering and comments relationships through `ftp:`. The comments part has no body reference, so it is read eagerly, as in s87a.
- **s88c.** Its footnotes relationship through `ftp:` (eager, no reference), and a footer through `ftp:`, used by a `w:footerReference` and unused.

Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 21 of 21 rows agree. The two times in Observed are the ends of the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at `45e7962fd961081ec1d7265f722e18dea18a6d53`, before the fix; `rejudge.mts` judged the same bytes at `8bfa4ea09ca2f09f95bac5e02e250ae71d73fb8d`.

- **A scheme target is refused whatever the relationship type, used or not.** Word offered recovery for all nine `ftp:` rows: the unused header, the package-level styles relationship, the unused image, settings, numbering, comments, footnotes, and the used and the unused footer.
- **Every plain-named calibration opened clean.** Every control did too. Every PDF Word saved renders the main document's `Hello`, and the used footer's calibration its `Footer 88` as well (`pdftotext`); no refused row left a PDF.

Word-valid at 45e7962f matches Word on 12 of 21 rows: it passed the nine `ftp:` rows with a `rels-broken` warning. At 8bfa4ea0 it matches on 21 of 21.

| Run    | Observed             | Specimen                           | Shape                                                                                                                                               | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 45e7962f | word-valid at 8bfa4ea0                              | strict at 8bfa4ea0                                                                               |
| ------ | -------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `s88a` | 17:59:21Z, 18:01:14Z | `header-unused-ftp`                | #1178: the main document's header-unused relationship targets ftp:header1.xml, stored word/ftp:header1.xml well-formed                              | `891f586f8caf8c2e` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:header1.xml`    |
| `s88a` | 17:59:21Z, 18:01:14Z | `header-unused-plain-calibration`  | calibration: the same header-unused relationship through its plain name                                                                             | `73524ed1cfbc0754` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | invalid: `paraid-missing-element@word/header1.xml`                                               |
| `s88a` | 17:59:21Z, 18:01:14Z | `pkgrels-styles-ftp`               | #1178: _rels/.rels relates a styles part through ftp:styles.xml, stored /ftp:styles.xml well-formed; the main document's styles relationship intact | `cc5e6f6db36ab5ba` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@_rels/.rels`                  | invalid: `rels-broken@_rels/.rels`, `rels-unreferenced@ftp:styles.xml`                           |
| `s88a` | 17:59:21Z, 18:01:14Z | `pkgrels-styles-plain-calibration` | calibration: the same _rels/.rels styles relationship through styles.xml, stored /styles.xml                                                        | `febb5d06dd3d5de0` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88a` | 17:59:21Z, 18:01:14Z | `image-ftp-unused`                 | #1178: an unused image relationship targets ftp:image1.png, stored word/ftp:image1.png                                                              | `b4960d71353fe11a` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:image1.png`     |
| `s88a` | 17:59:21Z, 18:01:14Z | `image-plain-unused-calibration`   | calibration: the same unused image relationship through image1.png                                                                                  | `08db7a5d6f8cfe29` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88a` | 17:59:21Z, 18:01:14Z | `s88a-control-minimal`             | control                                                                                                                                             | `1245c31a568f146f` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88b` | 18:03:07Z, 18:04:39Z | `settings-ftp`                     | #1178: the main document's settings relationship targets ftp:settings1.xml, stored word/ftp:settings1.xml well-formed                               | `338bb78f2320e770` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:settings1.xml`  |
| `s88b` | 18:03:07Z, 18:04:39Z | `settings-plain-calibration`       | calibration: the same settings relationship through its plain name                                                                                  | `988f880a91786037` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88b` | 18:03:07Z, 18:04:39Z | `numbering-ftp`                    | #1178: the main document's numbering relationship targets ftp:numbering1.xml, stored word/ftp:numbering1.xml well-formed                            | `7fd1f04ec6a5f62d` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:numbering1.xml` |
| `s88b` | 18:03:07Z, 18:04:39Z | `numbering-plain-calibration`      | calibration: the same numbering relationship through its plain name                                                                                 | `96739e2f15416cf3` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88b` | 18:03:07Z, 18:04:39Z | `comments-ftp`                     | #1178: the main document's comments relationship targets ftp:comments1.xml, stored word/ftp:comments1.xml well-formed                               | `fde357d68c78c5fb` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:comments1.xml`  |
| `s88b` | 18:03:07Z, 18:04:39Z | `comments-plain-calibration`       | calibration: the same comments relationship through its plain name                                                                                  | `e6026f5077f631e4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88b` | 18:03:07Z, 18:04:39Z | `s88b-control-minimal`             | control                                                                                                                                             | `1245c31a568f146f` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88c` | 18:06:37Z, 18:09:05Z | `footnotes-ftp`                    | #1178: the main document's footnotes relationship targets ftp:footnotes1.xml, stored word/ftp:footnotes1.xml well-formed                            | `258d8551d0ec6552` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:footnotes1.xml` |
| `s88c` | 18:06:37Z, 18:09:05Z | `footnotes-plain-calibration`      | calibration: the same footnotes relationship through its plain name                                                                                 | `d2513d3f4b937047` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |
| `s88c` | 18:06:37Z, 18:09:05Z | `footer-used-ftp`                  | #1178: the main document's footer-used relationship targets ftp:footer1.xml, stored word/ftp:footer1.xml well-formed                                | `904893c16a901f84` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:footer1.xml`    |
| `s88c` | 18:06:37Z, 18:09:05Z | `footer-used-plain-calibration`    | calibration: the same footer-used relationship through its plain name                                                                               | `1949f4d2d2d595e8` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | invalid: `paraid-missing-element@word/footer1.xml`                                               |
| `s88c` | 18:06:37Z, 18:09:05Z | `footer-unused-ftp`                | #1178: the main document's footer-unused relationship targets ftp:footer1.xml, stored word/ftp:footer1.xml well-formed                              | `bebc33b5a176b693` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `rels-broken@word/_rels/document.xml.rels` | invalid: `rels-broken@word/_rels/document.xml.rels`, `rels-unreferenced@word/ftp:footer1.xml`    |
| `s88c` | 18:06:37Z, 18:09:05Z | `footer-unused-plain-calibration`  | calibration: the same footer-unused relationship through its plain name                                                                             | `c12acb1a669d7ee6` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | invalid: `paraid-missing-element@word/footer1.xml`                                               |
| `s88c` | 18:06:37Z, 18:09:05Z | `s88c-control-minimal`             | control                                                                                                                                             | `1245c31a568f146f` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                               | valid                                                                                            |

<details><summary>Raw records, session 88</summary>

```jsonl
{"run": "s88a", "pass": 1, "name": "header-unused-ftp", "sha256": "891f586f8caf8c2e9bfdb60eae3a67fd1b8676207b4a925057c27800da4ac7cc", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00000__wfv__header-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 13:57:45.411 'Word found unreadable content in 00000__wfv__header-unused-ftp.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-30 13:57:46.047 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00000__wfv__header-unused-ftp.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__header-unused-ftp.docx; refusing to guess"}
{"run": "s88a", "pass": 2, "name": "header-unused-ftp", "sha256": "891f586f8caf8c2e9bfdb60eae3a67fd1b8676207b4a925057c27800da4ac7cc", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00000__wfv__header-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 13:59:46.422 'Word found unreadable content in 00000__wfv__header-unused-ftp.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-30 13:59:47.064 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00000__wfv__header-unused-ftp.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__header-unused-ftp.docx; refusing to guess"}
{"run": "s88a", "pass": 1, "name": "header-unused-plain-calibration", "sha256": "73524ed1cfbc0754e9d0244978fa74fba17b5661b5bde345338216a0aac6b770", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00001__wfv__header-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 2, "name": "header-unused-plain-calibration", "sha256": "73524ed1cfbc0754e9d0244978fa74fba17b5661b5bde345338216a0aac6b770", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00001__wfv__header-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 1, "name": "pkgrels-styles-ftp", "sha256": "cc5e6f6db36ab5ba111f2ae2cecce49836f1dbafe097b25ea326f4ac4676b7cd", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00004__wfv__pkgrels-styles-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 13:58:24.079 \"Word found unreadable content in 00004__wfv__pkgrels-styles-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\"", "2026-10-30 13:59:19.881 'Word experienced an error trying to open the file.\\nTry these suggestions.\\n* Check the file permis … very converter.\\n(00004__wfv__pkgrels-styles-ftp.docx)'"], "error": "repair prompt declined; Word could not read it"}
{"run": "s88a", "pass": 2, "name": "pkgrels-styles-ftp", "sha256": "cc5e6f6db36ab5ba111f2ae2cecce49836f1dbafe097b25ea326f4ac4676b7cd", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00004__wfv__pkgrels-styles-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:01:13.514 \"Word found unreadable content in 00004__wfv__pkgrels-styles-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__pkgrels-styles-ftp.docx; refusing to guess"}
{"run": "s88a", "pass": 1, "name": "pkgrels-styles-plain-calibration", "sha256": "febb5d06dd3d5de032983225487bec4d69c3001446c55bc300c7ceb65ae6ae04", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00005__wfv__pkgrels-styles-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-styles-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 2, "name": "pkgrels-styles-plain-calibration", "sha256": "febb5d06dd3d5de032983225487bec4d69c3001446c55bc300c7ceb65ae6ae04", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00005__wfv__pkgrels-styles-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-styles-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 1, "name": "image-ftp-unused", "sha256": "b4960d71353fe11a26791f133fc2cd1d6967d3124d73140b8092ef937979af25", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00002__wfv__image-ftp-unused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 13:57:59.144 \"Word found unreadable content in 00002__wfv__image-ftp-unused.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__image-ftp-unused.docx; refusing to guess"}
{"run": "s88a", "pass": 2, "name": "image-ftp-unused", "sha256": "b4960d71353fe11a26791f133fc2cd1d6967d3124d73140b8092ef937979af25", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00002__wfv__image-ftp-unused.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:00:12.213 \"Word found unreadable content in 00002__wfv__image-ftp-unused.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.\"", "2026-10-30 14:00:55.979 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ecovery converter. (00002__wfv__image-ftp-unused.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s88a", "pass": 1, "name": "image-plain-unused-calibration", "sha256": "08db7a5d6f8cfe29b60cc14d88c5497e1edb07f3eddb62611fcf77edc27c9bb0", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00003__wfv__image-plain-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF image-plain-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 2, "name": "image-plain-unused-calibration", "sha256": "08db7a5d6f8cfe29b60cc14d88c5497e1edb07f3eddb62611fcf77edc27c9bb0", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00003__wfv__image-plain-unused-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF image-plain-unused-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 1, "name": "s88a-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T17:59:21+00:00", "staged": "00006__wfv__s88a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88a", "pass": 2, "name": "s88a-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:01:14+00:00", "staged": "00006__wfv__s88a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 1, "name": "settings-ftp", "sha256": "338bb78f2320e77061ef72d33e844008870573a48c9d22b064bddb7e104c1664", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00005__wfv__settings-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:03:07.019 \"Word found unreadable content in 00005__wfv__settings-ftp.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__settings-ftp.docx; refusing to guess"}
{"run": "s88b", "pass": 2, "name": "settings-ftp", "sha256": "338bb78f2320e77061ef72d33e844008870573a48c9d22b064bddb7e104c1664", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00005__wfv__settings-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:04:37.610 'Word found unreadable content in 00005__wfv__settings-ftp.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.'"], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__settings-ftp.docx; refusing to guess"}
{"run": "s88b", "pass": 1, "name": "settings-plain-calibration", "sha256": "988f880a91786037645b4bc2801584678853af83cf4283d32a6c036a0211764c", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00006__wfv__settings-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 2, "name": "settings-plain-calibration", "sha256": "988f880a91786037645b4bc2801584678853af83cf4283d32a6c036a0211764c", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00006__wfv__settings-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF settings-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 1, "name": "numbering-ftp", "sha256": "7fd1f04ec6a5f62df39c2da5155cb0874e414f4af62232a1dd0b596f2ce8aefc", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00002__wfv__numbering-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:02:52.455 \"Word found unreadable content in 00002__wfv__numbering-ftp.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__numbering-ftp.docx; refusing to guess"}
{"run": "s88b", "pass": 2, "name": "numbering-ftp", "sha256": "7fd1f04ec6a5f62df39c2da5155cb0874e414f4af62232a1dd0b596f2ce8aefc", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00002__wfv__numbering-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:04:11.400 \"Word found unreadable content in 00002__wfv__numbering-ftp.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__numbering-ftp.docx; refusing to guess"}
{"run": "s88b", "pass": 1, "name": "numbering-plain-calibration", "sha256": "96739e2f15416cf3cfd1e93f2d9c9820c665b3149bf6f77bc71bb4a65b2713a7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00003__wfv__numbering-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 2, "name": "numbering-plain-calibration", "sha256": "96739e2f15416cf3cfd1e93f2d9c9820c665b3149bf6f77bc71bb4a65b2713a7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00003__wfv__numbering-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF numbering-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 1, "name": "comments-ftp", "sha256": "fde357d68c78c5fb77a2d8c3cc792c021927795b13c151f3eaf93cae4552f1f4", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00000__wfv__comments-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:01:50.220 \"Word found unreadable content in 00000__wfv__comments-ftp.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.\"", "2026-10-30 14:02:35.674 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … xt Recovery converter. (00000__wfv__comments-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s88b", "pass": 2, "name": "comments-ftp", "sha256": "fde357d68c78c5fb77a2d8c3cc792c021927795b13c151f3eaf93cae4552f1f4", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00000__wfv__comments-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:03:43.916 \"Word found unreadable content in 00000__wfv__comments-ftp.docx. Do you want to recover the contents … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__comments-ftp.docx; refusing to guess"}
{"run": "s88b", "pass": 1, "name": "comments-plain-calibration", "sha256": "e6026f5077f631e4faf9acea08b16bf6fdb2b8f9745b74cca0a5f60a5588c9aa", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00001__wfv__comments-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 2, "name": "comments-plain-calibration", "sha256": "e6026f5077f631e4faf9acea08b16bf6fdb2b8f9745b74cca0a5f60a5588c9aa", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00001__wfv__comments-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF comments-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 1, "name": "s88b-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:03:07+00:00", "staged": "00004__wfv__s88b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88b", "pass": 2, "name": "s88b-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:04:39+00:00", "staged": "00004__wfv__s88b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 1, "name": "footnotes-ftp", "sha256": "258d8551d0ec65520417a87f8d00a171793ceb1637dff97111927c5a48d386c7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00004__wfv__footnotes-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:06:36.084 \"Word found unreadable content in 00004__wfv__footnotes-ftp.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00004__wfv__footnotes-ftp.docx; refusing to guess"}
{"run": "s88c", "pass": 2, "name": "footnotes-ftp", "sha256": "258d8551d0ec65520417a87f8d00a171793ceb1637dff97111927c5a48d386c7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00004__wfv__footnotes-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:08:18.122 'Word found unreadable content in 00004__wfv__footnotes-ftp.docx. Do you want to recover the content … ? If you trust the source of this document, click Yes.'", "2026-10-30 14:09:05.568 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … t Recovery converter. (00004__wfv__footnotes-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s88c", "pass": 1, "name": "footnotes-plain-calibration", "sha256": "d2513d3f4b937047eedf94d159e2a3bf273b1d5df338ac2dc1aa5dbea3437be7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00005__wfv__footnotes-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 2, "name": "footnotes-plain-calibration", "sha256": "d2513d3f4b937047eedf94d159e2a3bf273b1d5df338ac2dc1aa5dbea3437be7", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00005__wfv__footnotes-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footnotes-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 1, "name": "footer-used-ftp", "sha256": "904893c16a901f84847ca71687bc49e05afc909a522495e381256cb19c01360b", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00002__wfv__footer-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:06:17.218 \"Word found unreadable content in 00002__wfv__footer-used-ftp.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__footer-used-ftp.docx; refusing to guess"}
{"run": "s88c", "pass": 2, "name": "footer-used-ftp", "sha256": "904893c16a901f84847ca71687bc49e05afc909a522495e381256cb19c01360b", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00002__wfv__footer-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:07:26.692 \"Word found unreadable content in 00002__wfv__footer-used-ftp.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00002__wfv__footer-used-ftp.docx; refusing to guess"}
{"run": "s88c", "pass": 1, "name": "footer-used-plain-calibration", "sha256": "1949f4d2d2d595e8681aab1d965624e75282ad7a701a28bb47254b9babe52b80", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00003__wfv__footer-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-used-plain-calibration_byword.pdf (15303 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 2, "name": "footer-used-plain-calibration", "sha256": "1949f4d2d2d595e8681aab1d965624e75282ad7a701a28bb47254b9babe52b80", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00003__wfv__footer-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-used-plain-calibration_byword.pdf (15303 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 1, "name": "footer-unused-ftp", "sha256": "bebc33b5a176b69344a886e580c223cac507c00a06428df5c8f423ed6b371115", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00000__wfv__footer-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:06:03.352 'Word found unreadable content in 00000__wfv__footer-unused-ftp.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.'", "2026-10-30 14:06:04.092 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … covery converter. (00000__wfv__footer-unused-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s88c", "pass": 2, "name": "footer-unused-ftp", "sha256": "bebc33b5a176b69344a886e580c223cac507c00a06428df5c8f423ed6b371115", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00000__wfv__footer-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 14:07:05.366 \"Word found unreadable content in 00000__wfv__footer-unused-ftp.docx. Do you want to recover the con … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00000__wfv__footer-unused-ftp.docx; refusing to guess"}
{"run": "s88c", "pass": 1, "name": "footer-unused-plain-calibration", "sha256": "c12acb1a669d7ee6bba71d4082fa001dacd6d3e1f2e4eb6cbd8124fda803adf2", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00001__wfv__footer-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 2, "name": "footer-unused-plain-calibration", "sha256": "c12acb1a669d7ee6bba71d4082fa001dacd6d3e1f2e4eb6cbd8124fda803adf2", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00001__wfv__footer-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF footer-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 1, "name": "s88c-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:06:37+00:00", "staged": "00006__wfv__s88c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s88c", "pass": 2, "name": "s88c-control-minimal", "sha256": "1245c31a568f146fc43581c3dc2292a769bdc2800caaf109fca543b9198aee73", "validatorRevision": "45e7962fd961081ec1d7265f722e18dea18a6d53", "observedAt": "2026-10-30T18:09:05+00:00", "staged": "00006__wfv__s88c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s88c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 88 builder, re-judge, cross-check and section scripts</summary>

Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed tree at the first revision, and the re-judge from the root of the committed tree at the second.

`s88builder.mts`:

```ts
// Session 88 (2026-10-30, #1178): the placements of a scheme-like internal target (`ftp:`) session 87 did not show
// Word, on the minimal package (`tests/support/minimal-docx.ts`). Session 87 (s87c/s87d) offered recovery for a used
// header and the styles part related through `ftp:` beside the well-formed `word/ftp:…` part the path spells, so every
// row here stores that part well-formed, and each placement has a plain-target calibration.
// s88a: a header the main document relates through `ftp:header1.xml` that no w:headerReference uses
//   (`header-ftp-unused`); a `_rels/.rels` styles relationship through `ftp:styles.xml`, stored /ftp:styles.xml, with
//   the main document's own styles relationship intact (`pkgrels-styles-ftp`); an unused image related through
//   `ftp:image1.png` (`image-ftp-unused`).
// s88b: the main document's settings, numbering and comments relationships through `ftp:` (comments with no body
//   reference: eager, as s87a).
// s88c: footnotes (eager, no reference) and a footer, used and unused, through `ftp:`.
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: CHUNK=s88a pnpm exec node --import tsx <abs path to this file>  (from the committed tree's root)
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const PKG_RELS = "_rels/.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const defaults = (ct: string, extension: string, type: string) =>
    replaceOnce(ct, '<Default Extension="xml"', `<Default Extension="${extension}" ContentType="${type}"/><Default Extension="xml"`);
/** `parts` with `r:` declared on the main document and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string | Uint8Array>, sect: string): Record<string, string | Uint8Array> => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
});

const HEADER = `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header 88</w:t></w:r></w:p></w:hdr>`;
const FOOTER = `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer 88</w:t></w:r></w:p></w:ftr>`;
const SETTINGS = `${XML_DECL}<w:settings xmlns:w="${W}"><w:defaultTabStop w:val="720"/></w:settings>`;
const NUMBERING = `${XML_DECL}<w:numbering xmlns:w="${W}"/>`;
const COMMENTS = `${XML_DECL}<w:comments xmlns:w="${W}"/>`;
const FOOTNOTES =
    `${XML_DECL}<w:footnotes xmlns:w="${W}">` +
    `<w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote>` +
    `<w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>` +
    `</w:footnotes>`;
// A 1x1 transparent PNG.
const PNG = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "base64");

type Story = { segment: string; type: string; xml: string | Uint8Array; sect?: (id: string) => string };
const STORIES: Record<string, Story> = {
    "header-unused": { segment: "header", type: `${WML}.header+xml`, xml: HEADER },
    settings: { segment: "settings", type: `${WML}.settings+xml`, xml: SETTINGS },
    numbering: { segment: "numbering", type: `${WML}.numbering+xml`, xml: NUMBERING },
    comments: { segment: "comments", type: `${WML}.comments+xml`, xml: COMMENTS },
    footnotes: { segment: "footnotes", type: `${WML}.footnotes+xml`, xml: FOOTNOTES },
    "footer-used": {
        segment: "footer",
        type: `${WML}.footer+xml`,
        xml: FOOTER,
        sect: (id) => `<w:footerReference w:type="default" r:id="${id}"/>`,
    },
    "footer-unused": { segment: "footer", type: `${WML}.footer+xml`, xml: FOOTER },
};
const fileFor = (segment: string) => `${segment}1.xml`;
/** The main document relating `story` through `prefix + <segment>1.xml`, stored at word/ under that same spelling. */
const related = (kind: string, prefix: string) => {
    const story = STORIES[kind]!;
    const target = `${prefix}${fileFor(story.segment)}`;
    return mainWith(
        {
            ...P,
            [`word/${target}`]: story.xml,
            [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdX", story.segment, target)),
            [CT]: overrides(P[CT]!, [`word/${target}`, story.type]),
        },
        story.sect?.("rIdX") ?? "",
    );
};
/** The package relationships part relating a styles part through `target`, stored at the package root. */
const pkgStyles = (target: string) => ({
    ...P,
    [target]: P["word/styles.xml"]!,
    [PKG_RELS]: appendRels(P[PKG_RELS]!, relationship("rIdS", "styles", target)),
    [CT]: overrides(P[CT]!, [target, `${WML}.styles+xml`]),
});
/** An unused image related through `target`, stored at word/ under that spelling. */
const image = (target: string) =>
    mainWith(
        {
            ...P,
            [`word/${target}`]: PNG,
            [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdI", "image", target)),
            [CT]: defaults(P[CT]!, "png", "image/png"),
        },
        "",
    );

type Row = [string, string, () => Promise<Uint8Array>];
const pair = (kind: string): Row[] => [
    [
        `${kind}-ftp`,
        `#1178: the main document's ${kind} relationship targets ftp:${fileFor(STORIES[kind]!.segment)}, stored word/ftp:${fileFor(STORIES[kind]!.segment)} well-formed`,
        () => buildDocx(related(kind, "ftp:")),
    ],
    [`${kind}-plain-calibration`, `calibration: the same ${kind} relationship through its plain name`, () => buildDocx(related(kind, ""))],
];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s88a: withControl("s88a", [
        ...pair("header-unused"),
        [
            "pkgrels-styles-ftp",
            "#1178: _rels/.rels relates a styles part through ftp:styles.xml, stored /ftp:styles.xml well-formed; the main document's styles relationship intact",
            () => buildDocx(pkgStyles("ftp:styles.xml")),
        ],
        [
            "pkgrels-styles-plain-calibration",
            "calibration: the same _rels/.rels styles relationship through styles.xml, stored /styles.xml",
            () => buildDocx(pkgStyles("styles.xml")),
        ],
        [
            "image-ftp-unused",
            "#1178: an unused image relationship targets ftp:image1.png, stored word/ftp:image1.png",
            () => buildDocx(image("ftp:image1.png")),
        ],
        [
            "image-plain-unused-calibration",
            "calibration: the same unused image relationship through image1.png",
            () => buildDocx(image("image1.png")),
        ],
    ]),
    s88b: withControl("s88b", [...pair("settings"), ...pair("numbering"), ...pair("comments")]),
    s88c: withControl("s88c", [...pair("footnotes"), ...pair("footer-used"), ...pair("footer-unused")]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
            warnings: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "warning")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`], warnings: [] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} warn=${row.wordValid.warnings.filter((w: string) => w.startsWith("rels")).join(",")} strict=${row.strict.valid}`,
    );
}
```

`rejudge.mts`:

```ts
// Judge the bytes session 88 showed Word (each chunk's src/) with the validator in WT, and record its revision per row.
// Run: WT=<tree> tsx <abs path to this file>
import { execFileSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(path.dirname(new URL(import.meta.url).pathname));
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const verdict = async (file: string, profile: "word-valid" | "strict") => {
    const r = await validate(file, { profile });
    return {
        valid: r.valid,
        errors: [
            ...new Set(
                r.issues
                    .filter((x: { severity: string }) => x.severity === "error")
                    .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
            ),
        ],
    };
};
const out: string[] = [];
for (const chunk of ["s88a", "s88b", "s88c"]) {
    for (const line of readFileSync(path.join(ROOT, chunk, "specimens.jsonl"), "utf8")
        .trim()
        .split("\n")) {
        const spec = JSON.parse(line);
        const file = path.join(ROOT, chunk, "src", spec.file);
        out.push(
            JSON.stringify({
                chunk,
                file: spec.file,
                validatorRevision: REVISION,
                wordValid: await verdict(file, "word-valid"),
                strict: await verdict(file, "strict"),
            }),
        );
    }
}
writeFileSync(path.join(ROOT, "s88", "rejudge.jsonl"), out.join("\n") + "\n");
console.log(out.length, "rows at", REVISION);
```

`compare.py`:

```python
"""Join the two runs of the session-88 chunks: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are its chunk's first pass (the chunk folder) and second pass (`pass2`), separate driver runs of
byte-identical copies. The validator verdicts come from the builder (`specimens.jsonl`, judged before the fixes) and
from `rejudge.jsonl` (the same bytes judged at the branch head).
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s88a", "s88b", "s88c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s88/rejudge.jsonl").read_text().splitlines())}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def matches(readings, valid):
    return (all(r in REJECTIONS for r in readings) and valid is False) or (all(r == "clean-open" for r in readings) and valid is True)


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    runs = [ROOT / label, ROOT / label / "pass2"]
    for name, spec in specs.items():
        for run in runs:
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        at_head = head[(label, name)]
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "readings": readings, "agreed": agreed, "outcome": TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown",
                     "wordValidBefore": spec["wordValid"]["valid"], "wordValidHead": at_head["wordValid"]["valid"],
                     "headRevision": at_head["validatorRevision"],
                     "matchesBefore": agreed and matches(readings, spec["wordValid"]["valid"]),
                     "matchesHead": agreed and matches(readings, at_head["wordValid"]["valid"])})
(ROOT / "s88/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<40} {r['outcome']:<27} before={r['wordValidBefore']!s:<5} head={r['wordValidHead']!s:<5} match={r['matchesBefore']}/{r['matchesHead']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| matches before:", sum(r["matchesBefore"] for r in rows),
      "| at head:", sum(r["matchesHead"] for r in rows))
```

`section.py`:

`````python
"""Render the session-88 part of docs/plans/evidence/word-probes-2026-10-24.md into s88/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, rejudge.jsonl (the same bytes judged at the branch head) and the
results.json compare.py writes. Revisions come from the rows, never from this script. The text Word rendered is read
from its own PDFs with pdftotext, so the narrative's "rendered" claim is checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s88a", "s88b", "s88c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s88/results.json").read_text())}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s88/rejudge.jsonl").read_text().splitlines())}


def cell(v):
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, before, after = [], [], [], [], set(), set()
for label in CHUNKS:
    for s in map(json.loads, (ROOT / label / "specimens.jsonl").read_text().splitlines()):
        result, h = results[(label, s["file"])], head[(label, s["file"])]
        runs = [ROOT / label, ROOT / label / "pass2"]
        before.add(s["validatorRevision"])
        after.add(h["validatorRevision"])
        times = [datetime.fromisoformat(manifest(r, s["file"])["run_at"]).astimezone(timezone.utc) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        cs = [checks(r)[s["file"]] for r in runs]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {s['issue'].replace('|', chr(92) + '|')} | "
            f"`{s['sha256'][:16]}` | {word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | {cell(s['wordValid'])} | "
            f"{cell(h['wordValid'])} | {cell(h['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, cs, times), start=1):
            out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s["validatorRevision"],
                   "observedAt": t.isoformat(), "staged": c["staged"], "logVerdict": c["logVerdict"], "tableVerdict": c["outcomesVerdict"],
                   "pdf": c["pdf"], "evidence": c["evidence"]}
            if manifest(r, s["file"]).get("error"):
                out["error"] = manifest(r, s["file"])["error"]
            raw.append(json.dumps(out, ensure_ascii=False))

assert len(before) == 1 and len(after) == 1, (before, after)
b, a = next(iter(before))[:8], next(iter(after))[:8]
# The narrative's claims, checked against results.json: every row's four readings agree; Word offered recovery for
# every ftp: row and opened clean every calibration and control; word-valid at the head matches Word on every row, and
# before the fix it missed exactly the nine ftp: rows.
for (label, file), r in results.items():
    assert r["agreed"], (label, file)
    scheme = "-ftp" in file
    assert r["outcome"] == ("unreadable-content-warning" if scheme else "clean-open"), (label, file, r["outcome"])
    assert r["matchesHead"], (label, file)
    assert r["matchesBefore"] is not scheme, (label, file)
# The driver opens files in name order (#671). Every PDF Word saved renders the main document's "Hello", and the used
# footer's calibration its footer text too.
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        assert [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()] == files, run
        for file in files:
            text = rendered(run, file)
            assert (text is None) is (results[(label, file)]["outcome"] != "clean-open"), (run, file)
            want = "Hello Footer 88" if file == "footer-used-plain-calibration.docx" else "Hello"
            assert text in (None, want), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}"
n = len(rows)
mb, ma = sum(r["matchesBefore"] for r in results.values()), sum(r["matchesHead"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 88: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {b} and {a}",
    "",
    f"The placements of a scheme-like internal target session 87 did not show Word ([#1178]({I}1178), the follow-up to "
    f"[#1127]({I}1127)). Session 87 offered recovery for a used header and the styles part related through `ftp:` beside "
    "the well-formed `word/ftp:…` part the path spells, so every row here stores that part well-formed, and each placement "
    "has a calibration through its plain name. Three chunks, on the minimal package.",
    "",
    f"- **s88a.** A header the main document relates through `ftp:header1.xml` that no `w:headerReference` uses; a "
    "`_rels/.rels` styles relationship through `ftp:styles.xml`, stored `/ftp:styles.xml`, with the main document's own "
    "styles relationship intact; an unused image related through `ftp:image1.png`.",
    "- **s88b.** The main document's settings, numbering and comments relationships through `ftp:`. The comments part "
    "has no body reference, so it is read eagerly, as in s87a.",
    "- **s88c.** Its footnotes relationship through `ftp:` (eager, no reference), and a footer through `ftp:`, used by a "
    "`w:footerReference` and unused.",
    "",
    "Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    f"`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {sum(r['agreed'] for r in results.values())} of {n} rows agree. The two times in Observed are the ends of "
    "the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at "
    f"`{next(iter(before))}`, before the fix; `rejudge.mts` judged the same bytes at `{next(iter(after))}`.",
    "",
    "- **A scheme target is refused whatever the relationship type, used or not.** Word offered recovery for all nine "
    "`ftp:` rows: the unused header, the package-level styles relationship, the unused image, settings, numbering, "
    "comments, footnotes, and the used and the unused footer.",
    "- **Every plain-named calibration opened clean.** Every control did too. Every PDF Word saved renders the main "
    "document's `Hello`, and the used footer's calibration its `Footer 88` as well (`pdftotext`); no refused row left a PDF.",
    "",
    f"Word-valid at {b} matches Word on {mb} of {n} rows: it passed the nine `ftp:` rows with a `rels-broken` warning. "
    f"At {a} it matches on {ma} of {n}.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {b} | word-valid at {a} | strict at {a} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 88</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 88 builder, re-judge, cross-check and section scripts</summary>",
    "",
    "Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed "
    "tree at the first revision, and the re-judge from the root of the committed tree at the second.",
    "",
]
for name, path, lang in (("s88builder.mts", ROOT / "s88builder.mts", "ts"), ("rejudge.mts", ROOT / "s88/rejudge.mts", "ts"),
                         ("compare.py", ROOT / "s88/compare.py", "python"), ("section.py", ROOT / "s88/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s88/section.md").write_text("\n".join(out))
print(n, "rows,", len(raw), "raw records,", mb, "/", ma, "match")
`````

</details>

### Session 89: 19:26Z–19:42Z on 2026-10-30, validator columns at 2a98048d and 9f8ecef6

The placements of a scheme-like internal target session 88 did not show Word ([#1184](https://github.com/jandira-tech/docx-validate/issues/1184), raised by the adversarial review of [#1182](https://github.com/jandira-tech/docx-validate/issues/1182)). Every `ftp:` row stores the part the path spells well-formed, and each placement has a calibration through its plain name. Three chunks, on the minimal package.

- **s89a.** `_rels/.rels` relates the core, extended (app) and custom properties and the thumbnail through `ftp:docProps/…`, stored `/ftp:docProps/…`. #1182 blocked these by extrapolation from s88a's styles row.
- **s89b.** A used header's own sidecar (`word/_rels/header1.xml.rels`) relates an image through `ftp:image1.png`, stored `word/ftp:image1.png`, which the header either embeds through `r:embed` in an inline drawing or does not use. #1182 kept these a warning.
- **s89c.** The same unused `ftp:image1.png` image in other sidecars: a used footer's, an unused header's, the styles part's and an unreferenced part's (`word/foo.xml`, which no relationship names).

Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 23 of 23 rows agree. The two times in Observed are the ends of the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at `2a98048de47687f7424fb6925b6fc5d8f377e11f`, before the fix; `rejudge.mts` judged the same bytes at `9f8ecef6d44894cb43c345700b05e4a58fa83988`. First attempts at s89a and s89c overlapped another session driving Word (its own `complex.docx` dialogs appear in the s89a one), so they were set aside unread, and every run here was taken with no other Word driver running.

- **The `_rels/.rels` block holds for the properties parts.** Word offered recovery for the core, extended and custom properties through `ftp:`, and opened each plain calibration clean, as #1182 predicted.
- **The thumbnail row shows nothing about the scheme.** Word offered recovery for its plain calibration too, a PNG thumbnail at `docProps/thumbnail.png` typed by a `png` Default, which word-valid passes ([#1186](https://github.com/jandira-tech/docx-validate/issues/1186)).
- **A scheme target blocks in every relationships part Word was shown.** Word offered recovery for both s89b `ftp:` rows in a used header's sidecar, the embedded image and the unused one, and for all four s89c sidecars, and opened every calibration clean, rendering the header's `Header 89` and the used footer's `Footer 89`. Sessions 79 and 80 had opened a folder target in such sidecars clean, so only the scheme target extends there.
- **Every control opened clean.** Every PDF Word saved renders the main document's `Hello` (`pdftotext`); no refused row left a PDF.

Word-valid at 2a98048d matches Word on 16 of 23 rows: it warned on the six s89b and s89c `ftp:` rows and passed the thumbnail calibration. At 9f8ecef6 it matches on 22 of 23; the thumbnail calibration is #1186.

| Run    | Observed             | Specimen                                  | Shape                                                                                                                                  | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 2a98048d             | word-valid at 9f8ecef6                             | strict at 9f8ecef6                                                                                                                                                              |
| ------ | -------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-core-ftp`                        | #1184: _rels/.rels relates the core part through ftp:docProps/core.xml, stored /ftp:docProps/core.xml well-formed                      | `11d309251214f106` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken@_rels/.rels` | invalid: `rels-broken@_rels/.rels`                 | invalid: `rels-broken@_rels/.rels`, `rels-unreferenced@ftp:docProps/core.xml`                                                                                                   |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-core-plain-calibration`          | calibration: the same _rels/.rels core relationship through docProps/core.xml                                                          | `18beaffd786cee52` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-app-ftp`                         | #1184: _rels/.rels relates the app part through ftp:docProps/app.xml, stored /ftp:docProps/app.xml well-formed                         | `ed9fef198491e862` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken@_rels/.rels` | invalid: `rels-broken@_rels/.rels`                 | invalid: `rels-broken@_rels/.rels`, `rels-unreferenced@ftp:docProps/app.xml`                                                                                                    |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-app-plain-calibration`           | calibration: the same _rels/.rels app relationship through docProps/app.xml                                                            | `019f53efe4035662` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-custom-ftp`                      | #1184: _rels/.rels relates the custom part through ftp:docProps/custom.xml, stored /ftp:docProps/custom.xml well-formed                | `3f9bc7afbcc188b2` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken@_rels/.rels` | invalid: `rels-broken@_rels/.rels`                 | invalid: `rels-broken@_rels/.rels`, `rels-unreferenced@ftp:docProps/custom.xml`                                                                                                 |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-custom-plain-calibration`        | calibration: the same _rels/.rels custom relationship through docProps/custom.xml                                                      | `b61ed8e8c970152d` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-thumbnail-ftp`                   | #1184: _rels/.rels relates the thumbnail part through ftp:docProps/thumbnail.png, stored /ftp:docProps/thumbnail.png well-formed       | `da702f369758adbb` | repair-warning | repair-warning | unreadable-content-warning | invalid: `rels-broken@_rels/.rels` | invalid: `rels-broken@_rels/.rels`                 | invalid: `rels-broken@_rels/.rels`, `rels-unreferenced@ftp:docProps/thumbnail.png`                                                                                              |
| `s89a` | 19:26:47Z, 19:27:26Z | `pkgrels-thumbnail-plain-calibration`     | calibration: the same _rels/.rels thumbnail relationship through docProps/thumbnail.png                                                | `c5e9ad3476b81e00` | repair-warning | repair-warning | unreadable-content-warning | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89a` | 19:26:47Z, 19:27:26Z | `s89a-control-minimal`                    | control                                                                                                                                | `fa0ecd0965d0ed8d` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89b` | 19:27:46Z, 19:28:03Z | `header-image-used-ftp`                   | #1184: a used header's own sidecar relates an image the header uses through r:embed through ftp:image1.png, stored word/ftp:image1.png | `09f69bbafb80b9e1` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/header1.xml.rels` | invalid: `rels-broken@word/_rels/header1.xml.rels`, `rels-unreferenced@word/ftp:image1.png`, `paraid-missing-element@word/header1.xml`                                          |
| `s89b` | 19:27:46Z, 19:28:03Z | `header-image-used-plain-calibration`     | calibration: the same header-sidecar image relationship through image1.png                                                             | `c165c231874524f1` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | invalid: `paraid-missing-element@word/header1.xml`                                                                                                                              |
| `s89b` | 19:27:46Z, 19:28:03Z | `header-image-unused-ftp`                 | #1184: a used header's own sidecar relates an image the header does not use through ftp:image1.png, stored word/ftp:image1.png         | `cbe17bbe3b293aa5` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/header1.xml.rels` | invalid: `rels-broken@word/_rels/header1.xml.rels`, `rels-unreferenced@word/ftp:image1.png`, `paraid-missing-element@word/header1.xml`                                          |
| `s89b` | 19:27:46Z, 19:28:03Z | `header-image-unused-plain-calibration`   | calibration: the same header-sidecar image relationship through image1.png                                                             | `4ce68e7f528df9a7` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | invalid: `paraid-missing-element@word/header1.xml`                                                                                                                              |
| `s89b` | 19:27:46Z, 19:28:03Z | `s89b-control-minimal`                    | control                                                                                                                                | `fa0ecd0965d0ed8d` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-footer-used-ftp`                 | #1184: the footer used part's own sidecar relates an unused image through ftp:image1.png, stored word/ftp:image1.png                   | `a9c23ef912780053` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/footer1.xml.rels` | invalid: `rels-broken@word/_rels/footer1.xml.rels`, `rels-unreferenced@word/ftp:image1.png`, `paraid-missing-element@word/footer1.xml`                                          |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-footer-used-plain-calibration`   | calibration: the same sidecar image relationship through image1.png                                                                    | `eee1d2025084e159` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | invalid: `paraid-missing-element@word/footer1.xml`                                                                                                                              |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-header-unused-ftp`               | #1184: the header unused part's own sidecar relates an unused image through ftp:image1.png, stored word/ftp:image1.png                 | `334ff0d92d1a7412` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/header1.xml.rels` | invalid: `rels-broken@word/_rels/header1.xml.rels`, `rels-unreferenced@word/ftp:image1.png`, `paraid-missing-element@word/header1.xml`                                          |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-header-unused-plain-calibration` | calibration: the same sidecar image relationship through image1.png                                                                    | `0b87b188021f58e2` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | invalid: `paraid-missing-element@word/header1.xml`                                                                                                                              |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-styles-ftp`                      | #1184: the styles part's own sidecar relates an unused image through ftp:image1.png, stored word/ftp:image1.png                        | `39da0788a7ae6307` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/styles.xml.rels`  | invalid: `rels-broken@word/_rels/styles.xml.rels`, `rels-unreferenced@word/ftp:image1.png`                                                                                      |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-styles-plain-calibration`        | calibration: the same sidecar image relationship through image1.png                                                                    | `ea103d716eadf5b7` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-unreferenced-ftp`                | #1184: an unreferenced word/foo.xml's own sidecar relates an unused image through ftp:image1.png, stored word/ftp:image1.png           | `8ff61ca0da5a6a4b` | repair-warning | repair-warning | unreadable-content-warning | valid                              | invalid: `rels-broken@word/_rels/foo.xml.rels`     | invalid: `rels-broken@word/_rels/foo.xml.rels`, `rels-unreferenced@word/foo.xml`, `rels-unreferenced@word/ftp:image1.png`, `xsd-summary@word/foo.xml`, `xsd-error@word/foo.xml` |
| `s89c` | 19:41:45Z, 19:42:16Z | `sidecar-unreferenced-plain-calibration`  | calibration: the same sidecar image relationship through image1.png                                                                    | `53b6333b156d7f28` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | invalid: `rels-unreferenced@word/foo.xml`, `xsd-summary@word/foo.xml`, `xsd-error@word/foo.xml`                                                                                 |
| `s89c` | 19:41:45Z, 19:42:16Z | `s89c-control-minimal`                    | control                                                                                                                                | `0028ee126637f94f` | clean-open     | clean-open     | clean-open                 | valid                              | valid                                              | valid                                                                                                                                                                           |

<details><summary>Raw records, session 89</summary>

```jsonl
{"run": "s89a", "pass": 1, "name": "pkgrels-core-ftp", "sha256": "11d309251214f10691ba2ee78818d7d8c69120567ff5484a619b67008a531e2c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00002__wfv__pkgrels-core-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:26:33.282 'Word found unreadable content in 00002__wfv__pkgrels-core-ftp.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:26:33.828 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ecovery converter. (00002__wfv__pkgrels-core-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 2, "name": "pkgrels-core-ftp", "sha256": "11d309251214f10691ba2ee78818d7d8c69120567ff5484a619b67008a531e2c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00002__wfv__pkgrels-core-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:26.341 'Word found unreadable content in 00002__wfv__pkgrels-core-ftp.docx. Do you want to recover the cont … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:26.876 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ecovery converter. (00002__wfv__pkgrels-core-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 1, "name": "pkgrels-core-plain-calibration", "sha256": "18beaffd786cee52b4c70138ddb0ad6eaf0ebaf9e8baab18be878285f324ca8e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00003__wfv__pkgrels-core-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-core-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 2, "name": "pkgrels-core-plain-calibration", "sha256": "18beaffd786cee52b4c70138ddb0ad6eaf0ebaf9e8baab18be878285f324ca8e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00003__wfv__pkgrels-core-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-core-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 1, "name": "pkgrels-app-ftp", "sha256": "ed9fef198491e8621540ac68394d994f15e8920e032cd54a6f6976efdeacdc27", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00000__wfv__pkgrels-app-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:26:28.876 'Word found unreadable content in 00000__wfv__pkgrels-app-ftp.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:26:29.694 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00000__wfv__pkgrels-app-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 2, "name": "pkgrels-app-ftp", "sha256": "ed9fef198491e8621540ac68394d994f15e8920e032cd54a6f6976efdeacdc27", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00000__wfv__pkgrels-app-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:04.695 'Word found unreadable content in 00000__wfv__pkgrels-app-ftp.docx. Do you want to recover the conte … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:05.270 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … Recovery converter. (00000__wfv__pkgrels-app-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 1, "name": "pkgrels-app-plain-calibration", "sha256": "019f53efe40356623055b3d09e7ba436bd20b2615d92493583a05ef3c14a6e27", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00001__wfv__pkgrels-app-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-app-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 2, "name": "pkgrels-app-plain-calibration", "sha256": "019f53efe40356623055b3d09e7ba436bd20b2615d92493583a05ef3c14a6e27", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00001__wfv__pkgrels-app-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-app-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 1, "name": "pkgrels-custom-ftp", "sha256": "3f9bc7afbcc188b2b029b0d60ed8b9710b04b51d763910e0e18e2a2b02365f3d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00004__wfv__pkgrels-custom-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:26:37.507 'Word found unreadable content in 00004__wfv__pkgrels-custom-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:26:38.053 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00004__wfv__pkgrels-custom-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 2, "name": "pkgrels-custom-ftp", "sha256": "3f9bc7afbcc188b2b029b0d60ed8b9710b04b51d763910e0e18e2a2b02365f3d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00004__wfv__pkgrels-custom-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:13.390 'Word found unreadable content in 00004__wfv__pkgrels-custom-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:14.216 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00004__wfv__pkgrels-custom-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 1, "name": "pkgrels-custom-plain-calibration", "sha256": "b61ed8e8c970152d81e29cc7f0ebcda405b8d66ce751282f73af66430c84066c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00005__wfv__pkgrels-custom-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-custom-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 2, "name": "pkgrels-custom-plain-calibration", "sha256": "b61ed8e8c970152d81e29cc7f0ebcda405b8d66ce751282f73af66430c84066c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00005__wfv__pkgrels-custom-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF pkgrels-custom-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 1, "name": "pkgrels-thumbnail-ftp", "sha256": "da702f369758adbb7aee3ca1e0e012709db51d27b381f586e579d270965b64c5", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00006__wfv__pkgrels-thumbnail-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:26:41.741 'Word found unreadable content in 00006__wfv__pkgrels-thumbnail-ftp.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:26:42.303 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__pkgrels-thumbnail-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 2, "name": "pkgrels-thumbnail-ftp", "sha256": "da702f369758adbb7aee3ca1e0e012709db51d27b381f586e579d270965b64c5", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00006__wfv__pkgrels-thumbnail-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:17.842 'Word found unreadable content in 00006__wfv__pkgrels-thumbnail-ftp.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:18.689 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00006__wfv__pkgrels-thumbnail-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 1, "name": "pkgrels-thumbnail-plain-calibration", "sha256": "c5e9ad3476b81e00f52f37a3d0dc16b60c7b8c575b8d75543f8ec9946b9e9df4", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00007__wfv__pkgrels-thumbnail-plain-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:26:45.925 'Word found unreadable content in 00007__wfv__pkgrels-thumbnail-plain-calibration.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:26:46.461 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__pkgrels-thumbnail-plain-c...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 2, "name": "pkgrels-thumbnail-plain-calibration", "sha256": "c5e9ad3476b81e00f52f37a3d0dc16b60c7b8c575b8d75543f8ec9946b9e9df4", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00007__wfv__pkgrels-thumbnail-plain-calibration.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:22.109 'Word found unreadable content in 00007__wfv__pkgrels-thumbnail-plain-calibration.docx. Do you want  … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:22.757 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__pkgrels-thumbnail-plain-c...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89a", "pass": 1, "name": "s89a-control-minimal", "sha256": "fa0ecd0965d0ed8d173b5eec0a7ca776d618c635870f01545b376058eea9942d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:26:47+00:00", "staged": "00008__wfv__s89a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89a", "pass": 2, "name": "s89a-control-minimal", "sha256": "fa0ecd0965d0ed8d173b5eec0a7ca776d618c635870f01545b376058eea9942d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:26+00:00", "staged": "00008__wfv__s89a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 1, "name": "header-image-used-ftp", "sha256": "09f69bbafb80b9e12677f1c89e7ca464ac80916294015cb40410fc1ac3910b8e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:46+00:00", "staged": "00002__wfv__header-image-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:44.591 'Word found unreadable content in 00002__wfv__header-image-used-ftp.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:45.110 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__header-image-used-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89b", "pass": 2, "name": "header-image-used-ftp", "sha256": "09f69bbafb80b9e12677f1c89e7ca464ac80916294015cb40410fc1ac3910b8e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:28:03+00:00", "staged": "00002__wfv__header-image-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:58.377 'Word found unreadable content in 00002__wfv__header-image-used-ftp.docx. Do you want to recover the … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:58.921 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … ry converter. (00002__wfv__header-image-used-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89b", "pass": 1, "name": "header-image-used-plain-calibration", "sha256": "c165c231874524f175b2e2c25a82d6461ba74c3c31a07cf3fd399ec7c36d74d1", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:46+00:00", "staged": "00003__wfv__header-image-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-image-used-plain-calibration_byword.pdf (16795 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 2, "name": "header-image-used-plain-calibration", "sha256": "c165c231874524f175b2e2c25a82d6461ba74c3c31a07cf3fd399ec7c36d74d1", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:28:03+00:00", "staged": "00003__wfv__header-image-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-image-used-plain-calibration_byword.pdf (16795 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 1, "name": "header-image-unused-ftp", "sha256": "cbe17bbe3b293aa5a85c24747b74632ee9bb6d99472520190e9257eb4fab391c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:46+00:00", "staged": "00000__wfv__header-image-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:40.316 'Word found unreadable content in 00000__wfv__header-image-unused-ftp.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:40.870 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header-image-unused-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89b", "pass": 2, "name": "header-image-unused-ftp", "sha256": "cbe17bbe3b293aa5a85c24747b74632ee9bb6d99472520190e9257eb4fab391c", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:28:03+00:00", "staged": "00000__wfv__header-image-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:27:54.149 'Word found unreadable content in 00000__wfv__header-image-unused-ftp.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:27:54.670 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00000__wfv__header-image-unused-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89b", "pass": 1, "name": "header-image-unused-plain-calibration", "sha256": "4ce68e7f528df9a7b0f4bed17adc689395083168331b4217ec1f85e6014d5362", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:46+00:00", "staged": "00001__wfv__header-image-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-image-unused-plain-calibration_byword.pdf (16216 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 2, "name": "header-image-unused-plain-calibration", "sha256": "4ce68e7f528df9a7b0f4bed17adc689395083168331b4217ec1f85e6014d5362", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:28:03+00:00", "staged": "00001__wfv__header-image-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF header-image-unused-plain-calibration_byword.pdf (16216 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 1, "name": "s89b-control-minimal", "sha256": "fa0ecd0965d0ed8d173b5eec0a7ca776d618c635870f01545b376058eea9942d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:27:46+00:00", "staged": "00004__wfv__s89b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89b", "pass": 2, "name": "s89b-control-minimal", "sha256": "fa0ecd0965d0ed8d173b5eec0a7ca776d618c635870f01545b376058eea9942d", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:28:03+00:00", "staged": "00004__wfv__s89b-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89b-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 1, "name": "sidecar-footer-used-ftp", "sha256": "a9c23ef91278005319dce771af634627faf4cfc2f285d69f7949a5ebf8b716cb", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00001__wfv__sidecar-footer-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:41:31.102 'Word found unreadable content in 00001__wfv__sidecar-footer-used-ftp.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:41:31.923 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__sidecar-footer-used-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 2, "name": "sidecar-footer-used-ftp", "sha256": "a9c23ef91278005319dce771af634627faf4cfc2f285d69f7949a5ebf8b716cb", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00001__wfv__sidecar-footer-used-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:02.898 'Word found unreadable content in 00001__wfv__sidecar-footer-used-ftp.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:03.423 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00001__wfv__sidecar-footer-used-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 1, "name": "sidecar-footer-used-plain-calibration", "sha256": "eee1d2025084e159faab653f4a7e3a4244385a1136b49ad3d136215a117fc661", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00002__wfv__sidecar-footer-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-footer-used-plain-calibration_byword.pdf (15661 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 2, "name": "sidecar-footer-used-plain-calibration", "sha256": "eee1d2025084e159faab653f4a7e3a4244385a1136b49ad3d136215a117fc661", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00002__wfv__sidecar-footer-used-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-footer-used-plain-calibration_byword.pdf (15661 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 1, "name": "sidecar-header-unused-ftp", "sha256": "334ff0d92d1a741294b6e797df2db1a0650716b1f6b5003b21989658bda57151", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00003__wfv__sidecar-header-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:41:35.531 'Word found unreadable content in 00003__wfv__sidecar-header-unused-ftp.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:41:36.073 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__sidecar-header-unused-ftp...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 2, "name": "sidecar-header-unused-ftp", "sha256": "334ff0d92d1a741294b6e797df2db1a0650716b1f6b5003b21989658bda57151", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00003__wfv__sidecar-header-unused-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:07.119 'Word found unreadable content in 00003__wfv__sidecar-header-unused-ftp.docx. Do you want to recover … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:07.656 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__sidecar-header-unused-ftp...)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 1, "name": "sidecar-header-unused-plain-calibration", "sha256": "0b87b188021f58e2d6babdc6e60a86511d8b29c5f47ffde896dc5b77c215558e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00004__wfv__sidecar-header-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-header-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 2, "name": "sidecar-header-unused-plain-calibration", "sha256": "0b87b188021f58e2d6babdc6e60a86511d8b29c5f47ffde896dc5b77c215558e", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00004__wfv__sidecar-header-unused-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-header-unused-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 1, "name": "sidecar-styles-ftp", "sha256": "39da0788a7ae630765e2de1a03c99a1b8bc5e14318fd02a530ae0c965f7d703b", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00005__wfv__sidecar-styles-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:41:39.786 'Word found unreadable content in 00005__wfv__sidecar-styles-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:41:40.306 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00005__wfv__sidecar-styles-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 2, "name": "sidecar-styles-ftp", "sha256": "39da0788a7ae630765e2de1a03c99a1b8bc5e14318fd02a530ae0c965f7d703b", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00005__wfv__sidecar-styles-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:11.385 'Word found unreadable content in 00005__wfv__sidecar-styles-ftp.docx. Do you want to recover the co … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:11.916 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … overy converter. (00005__wfv__sidecar-styles-ftp.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 1, "name": "sidecar-styles-plain-calibration", "sha256": "ea103d716eadf5b783dfe5f0d952775db49329aab99feddb19b430ec371f5c99", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00006__wfv__sidecar-styles-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-styles-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 2, "name": "sidecar-styles-plain-calibration", "sha256": "ea103d716eadf5b783dfe5f0d952775db49329aab99feddb19b430ec371f5c99", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00006__wfv__sidecar-styles-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-styles-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 1, "name": "sidecar-unreferenced-ftp", "sha256": "8ff61ca0da5a6a4b51972de0a8263ed62d0f2923de0b373bf5b2db46379861d9", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00007__wfv__sidecar-unreferenced-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:41:44.048 'Word found unreadable content in 00007__wfv__sidecar-unreferenced-ftp.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:41:44.590 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__sidecar-unreferenced-ftp....)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 2, "name": "sidecar-unreferenced-ftp", "sha256": "8ff61ca0da5a6a4b51972de0a8263ed62d0f2923de0b373bf5b2db46379861d9", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00007__wfv__sidecar-unreferenced-ftp.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:15.637 'Word found unreadable content in 00007__wfv__sidecar-unreferenced-ftp.docx. Do you want to recover  … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:16.173 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00007__wfv__sidecar-unreferenced-ftp....)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s89c", "pass": 1, "name": "sidecar-unreferenced-plain-calibration", "sha256": "53b6333b156d7f28661ba868587712c29a263d1679978e04f0a4c3cb3948ced3", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00008__wfv__sidecar-unreferenced-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-unreferenced-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 2, "name": "sidecar-unreferenced-plain-calibration", "sha256": "53b6333b156d7f28661ba868587712c29a263d1679978e04f0a4c3cb3948ced3", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00008__wfv__sidecar-unreferenced-plain-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF sidecar-unreferenced-plain-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 1, "name": "s89c-control-minimal", "sha256": "0028ee126637f94fb1544361812bbc067cd45837f67673ce6bcce41c8023d472", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:41:45+00:00", "staged": "00000__wfv__s89c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s89c", "pass": 2, "name": "s89c-control-minimal", "sha256": "0028ee126637f94fb1544361812bbc067cd45837f67673ce6bcce41c8023d472", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:16+00:00", "staged": "00000__wfv__s89c-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s89c-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 89 builder, re-judge, cross-check and section scripts</summary>

Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed tree at the first revision, and the re-judge from the root of the committed tree at the second.

`s89builder.mts`:

```ts
// Session 89 (2026-10-30, #1184): the placements of a scheme-like internal target (`ftp:`) session 88 did not show
// Word, on the minimal package (`tests/support/minimal-docx.ts`). Every ftp: row stores the part the path spells
// well-formed, and each placement has a plain-target calibration.
// s89a: `_rels/.rels` relates the core, extended (app) and custom properties and the thumbnail through `ftp:docProps/…`,
//   stored /ftp:docProps/… (#1182 blocks these by extrapolation from s88a's styles row).
// s89b: a used header's own sidecar (word/_rels/header1.xml.rels) relates an image through `ftp:image1.png`, stored
//   word/ftp:image1.png, that the header uses through r:embed, and one it does not use (#1182 keeps these a warning).
// s89c: the same unused image through `ftp:image1.png` in other sidecars: a used footer's, an unused header's, the
//   styles part's and an unreferenced part's (word/foo.xml, no relationship names it).
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: CHUNK=s89a pnpm exec node --import tsx <abs path to this file>  (from the committed tree's root)
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const PKG_RELS = "_rels/.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const defaults = (ct: string, extension: string, type: string) =>
    replaceOnce(ct, '<Default Extension="xml"', `<Default Extension="${extension}" ContentType="${type}"/><Default Extension="xml"`);
/** `parts` with `r:` declared on the main document and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string | Uint8Array>, sect: string): Record<string, string | Uint8Array> => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
});

const PKG = "http://schemas.openxmlformats.org/package/2006/relationships";
const A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
const WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
// A 1x1 transparent PNG.
const PNG = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "base64");
const CORE = `${XML_DECL}<cp:coreProperties xmlns:cp="${PKG.replace("relationships", "metadata/core-properties")}" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>Probe 89</dc:title></cp:coreProperties>`;
const APP = `${XML_DECL}<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>Microsoft Office Word</Application></Properties>`;
const CUSTOM =
    `${XML_DECL}<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">` +
    `<property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="Probe"><vt:lpwstr>89</vt:lpwstr></property></Properties>`;

type Prop = { type: string; file: string; xml: string | Uint8Array; contentType?: string };
const PROPS: Record<string, Prop> = {
    core: {
        type: `${PKG}/metadata/core-properties`,
        file: "core.xml",
        xml: CORE,
        contentType: "application/vnd.openxmlformats-package.core-properties+xml",
    },
    app: {
        type: `${R}/extended-properties`,
        file: "app.xml",
        xml: APP,
        contentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml",
    },
    custom: {
        type: `${R}/custom-properties`,
        file: "custom.xml",
        xml: CUSTOM,
        contentType: "application/vnd.openxmlformats-officedocument.custom-properties+xml",
    },
    thumbnail: { type: `${PKG}/metadata/thumbnail`, file: "thumbnail.png", xml: PNG },
};
/** `_rels/.rels` relating the `kind` part through `prefix + docProps/<file>`, stored at the package root under that spelling. */
const pkgProp = (kind: string, prefix: string) => {
    const prop = PROPS[kind]!;
    const target = `${prefix}docProps/${prop.file}`;
    return {
        ...P,
        [target]: prop.xml,
        [PKG_RELS]: appendRels(P[PKG_RELS]!, `<Relationship Id="rIdP" Type="${prop.type}" Target="${target}"/>`),
        [CT]: prop.contentType ? overrides(P[CT]!, [target, prop.contentType]) : defaults(P[CT]!, "png", "image/png"),
    };
};

const DRAWING =
    `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="95250" cy="95250"/><wp:docPr id="1" name="Picture 1"/>` +
    `<a:graphic xmlns:a="${A}"><a:graphicData uri="${PIC}"><pic:pic xmlns:pic="${PIC}"><pic:nvPicPr><pic:cNvPr id="1" name="image1.png"/><pic:cNvPicPr/></pic:nvPicPr>` +
    `<pic:blipFill><a:blip r:embed="rIdI"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>` +
    `<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="95250" cy="95250"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
const header = (used: boolean) =>
    `${XML_DECL}<w:hdr xmlns:w="${W}" xmlns:r="${R}" xmlns:wp="${WP}"><w:p><w:r><w:t>Header 89</w:t></w:r>${used ? DRAWING : ""}</w:p></w:hdr>`;
/** A used header whose own sidecar relates an image through `prefix + image1.png`, stored at word/ under that spelling. */
const headerImage = (used: boolean, prefix: string) => {
    const target = `${prefix}image1.png`;
    return mainWith(
        {
            ...P,
            "word/header1.xml": header(used),
            "word/_rels/header1.xml.rels": `${XML_DECL}<Relationships xmlns="${PKG}">${relationship("rIdI", "image", target)}</Relationships>`,
            [`word/${target}`]: PNG,
            [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: defaults(overrides(P[CT]!, ["word/header1.xml", `${WML}.header+xml`]), "png", "image/png"),
        },
        `<w:headerReference w:type="default" r:id="rIdH"/>`,
    );
};

type Row = [string, string, () => Promise<Uint8Array>];
const FOOTER89 = `${XML_DECL}<w:ftr xmlns:w="${W}"><w:p><w:r><w:t>Footer 89</w:t></w:r></w:p></w:ftr>`;
const HEADER89 = `${XML_DECL}<w:hdr xmlns:w="${W}"><w:p><w:r><w:t>Header 89</w:t></w:r></w:p></w:hdr>`;
const imageRels = (target: string) => `${XML_DECL}<Relationships xmlns="${PKG}">${relationship("rIdI", "image", target)}</Relationships>`;
/** A part whose own sidecar relates an unused image through `prefix + image1.png`, stored at word/ under that spelling. */
const sidecarImage = (owner: string, prefix: string) => {
    const target = `${prefix}image1.png`;
    const base: Record<string, string | Uint8Array> = { ...P, [`word/${target}`]: PNG, [CT]: defaults(P[CT]!, "png", "image/png") };
    if (owner === "footer-used")
        return mainWith(
            {
                ...base,
                "word/footer1.xml": FOOTER89,
                "word/_rels/footer1.xml.rels": imageRels(target),
                [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdF", "footer", "footer1.xml")),
                [CT]: overrides(base[CT] as string, ["word/footer1.xml", `${WML}.footer+xml`]),
            },
            `<w:footerReference w:type="default" r:id="rIdF"/>`,
        );
    if (owner === "header-unused")
        return {
            ...base,
            "word/header1.xml": HEADER89,
            "word/_rels/header1.xml.rels": imageRels(target),
            [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdH", "header", "header1.xml")),
            [CT]: overrides(base[CT] as string, ["word/header1.xml", `${WML}.header+xml`]),
        };
    if (owner === "styles") return { ...base, "word/_rels/styles.xml.rels": imageRels(target) };
    // An unreferenced part: no relationship names word/foo.xml.
    return { ...base, "word/foo.xml": `${XML_DECL}<foo/>`, "word/_rels/foo.xml.rels": imageRels(target) };
};
const sidecarPair = (owner: string): Row[] => [
    [
        `sidecar-${owner}-ftp`,
        `#1184: ${owner === "unreferenced" ? "an unreferenced word/foo.xml" : `the ${owner.replace("-", " ")} part`}'s own sidecar relates an unused image through ftp:image1.png, stored word/ftp:image1.png`,
        () => buildDocx(sidecarImage(owner, "ftp:")),
    ],
    [
        `sidecar-${owner}-plain-calibration`,
        `calibration: the same sidecar image relationship through image1.png`,
        () => buildDocx(sidecarImage(owner, "")),
    ],
];

const propPair = (kind: string): Row[] => [
    [
        `pkgrels-${kind}-ftp`,
        `#1184: _rels/.rels relates the ${kind} part through ftp:docProps/${PROPS[kind]!.file}, stored /ftp:docProps/${PROPS[kind]!.file} well-formed`,
        () => buildDocx(pkgProp(kind, "ftp:")),
    ],
    [
        `pkgrels-${kind}-plain-calibration`,
        `calibration: the same _rels/.rels ${kind} relationship through docProps/${PROPS[kind]!.file}`,
        () => buildDocx(pkgProp(kind, "")),
    ],
];
const headerPair = (used: boolean): Row[] => {
    const kind = used ? "used" : "unused";
    return [
        [
            `header-image-${kind}-ftp`,
            `#1184: a used header's own sidecar relates an image the header ${used ? "uses through r:embed" : "does not use"} through ftp:image1.png, stored word/ftp:image1.png`,
            () => buildDocx(headerImage(used, "ftp:")),
        ],
        [
            `header-image-${kind}-plain-calibration`,
            `calibration: the same header-sidecar image relationship through image1.png`,
            () => buildDocx(headerImage(used, "")),
        ],
    ];
};
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s89a: withControl("s89a", [...propPair("core"), ...propPair("app"), ...propPair("custom"), ...propPair("thumbnail")]),
    s89b: withControl("s89b", [...headerPair(true), ...headerPair(false)]),
    s89c: withControl("s89c", [
        ...sidecarPair("footer-used"),
        ...sidecarPair("header-unused"),
        ...sidecarPair("styles"),
        ...sidecarPair("unreferenced"),
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
            warnings: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "warning")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`], warnings: [] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} warn=${row.wordValid.warnings.filter((w: string) => w.startsWith("rels")).join(",")} strict=${row.strict.valid}`,
    );
}
```

`rejudge.mts`:

```ts
// Judge the bytes session 89 showed Word (each chunk's src/) with the validator in WT, and record its revision per row.
// Run: WT=<tree> tsx <abs path to this file>
import { execFileSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(path.dirname(new URL(import.meta.url).pathname));
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const verdict = async (file: string, profile: "word-valid" | "strict") => {
    const r = await validate(file, { profile });
    return {
        valid: r.valid,
        errors: [
            ...new Set(
                r.issues
                    .filter((x: { severity: string }) => x.severity === "error")
                    .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
            ),
        ],
    };
};
const out: string[] = [];
for (const chunk of ["s89a", "s89b", "s89c"]) {
    for (const line of readFileSync(path.join(ROOT, chunk, "specimens.jsonl"), "utf8")
        .trim()
        .split("\n")) {
        const spec = JSON.parse(line);
        const file = path.join(ROOT, chunk, "src", spec.file);
        out.push(
            JSON.stringify({
                chunk,
                file: spec.file,
                validatorRevision: REVISION,
                wordValid: await verdict(file, "word-valid"),
                strict: await verdict(file, "strict"),
            }),
        );
    }
}
writeFileSync(path.join(ROOT, "s89", "rejudge.jsonl"), out.join("\n") + "\n");
console.log(out.length, "rows at", REVISION);
```

`compare.py`:

```python
"""Join the two runs of the session-89 chunks: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are its chunk's first pass (the chunk folder) and second pass (`pass2`), separate driver runs of
byte-identical copies. The validator verdicts come from the builder (`specimens.jsonl`, judged before the fixes) and
from `rejudge.jsonl` (the same bytes judged at the branch head).
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s89a", "s89b", "s89c")
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s89/rejudge.jsonl").read_text().splitlines())}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def matches(readings, valid):
    return (all(r in REJECTIONS for r in readings) and valid is False) or (all(r == "clean-open" for r in readings) and valid is True)


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    runs = [ROOT / label, ROOT / label / "pass2"]
    for name, spec in specs.items():
        for run in runs:
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        at_head = head[(label, name)]
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "readings": readings, "agreed": agreed, "outcome": TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown",
                     "wordValidBefore": spec["wordValid"]["valid"], "wordValidHead": at_head["wordValid"]["valid"],
                     "headRevision": at_head["validatorRevision"],
                     "matchesBefore": agreed and matches(readings, spec["wordValid"]["valid"]),
                     "matchesHead": agreed and matches(readings, at_head["wordValid"]["valid"])})
(ROOT / "s89/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<40} {r['outcome']:<27} before={r['wordValidBefore']!s:<5} head={r['wordValidHead']!s:<5} match={r['matchesBefore']}/{r['matchesHead']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| matches before:", sum(r["matchesBefore"] for r in rows),
      "| at head:", sum(r["matchesHead"] for r in rows))
```

`section.py`:

`````python
"""Render the session-89 part of docs/plans/evidence/word-probes-2026-10-24.md into s89/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, rejudge.jsonl (the same bytes judged at the branch head) and the
results.json compare.py writes. Revisions come from the rows, never from this script. The text Word rendered is read
from its own PDFs with pdftotext, so the narrative's "rendered" claim is checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s89a", "s89b", "s89c")
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s89/results.json").read_text())}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s89/rejudge.jsonl").read_text().splitlines())}


def cell(v):
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, before, after = [], [], [], [], set(), set()
for label in CHUNKS:
    for s in map(json.loads, (ROOT / label / "specimens.jsonl").read_text().splitlines()):
        result, h = results[(label, s["file"])], head[(label, s["file"])]
        runs = [ROOT / label, ROOT / label / "pass2"]
        before.add(s["validatorRevision"])
        after.add(h["validatorRevision"])
        times = [datetime.fromisoformat(manifest(r, s["file"])["run_at"]).astimezone(timezone.utc) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        cs = [checks(r)[s["file"]] for r in runs]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {s['issue'].replace('|', chr(92) + '|')} | "
            f"`{s['sha256'][:16]}` | {word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | {cell(s['wordValid'])} | "
            f"{cell(h['wordValid'])} | {cell(h['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, cs, times), start=1):
            out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s["validatorRevision"],
                   "observedAt": t.isoformat(), "staged": c["staged"], "logVerdict": c["logVerdict"], "tableVerdict": c["outcomesVerdict"],
                   "pdf": c["pdf"], "evidence": c["evidence"]}
            if manifest(r, s["file"]).get("error"):
                out["error"] = manifest(r, s["file"])["error"]
            raw.append(json.dumps(out, ensure_ascii=False))

assert len(before) == 1 and len(after) == 1, (before, after)
b, a = next(iter(before))[:8], next(iter(after))[:8]
# The narrative's claims, checked against results.json: every row's four readings agree; Word offered recovery for
# every ftp: row and for the thumbnail calibration, and opened clean every other calibration and control; word-valid at
# the head matches Word on every row but the thumbnail calibration (#1186), and before the fix it also missed exactly the
# s89b and s89c ftp: rows.
THUMB = "pkgrels-thumbnail-plain-calibration.docx"
for (label, file), r in results.items():
    assert r["agreed"], (label, file)
    scheme = "-ftp" in file
    assert r["outcome"] == ("unreadable-content-warning" if scheme or file == THUMB else "clean-open"), (label, file, r["outcome"])
    assert r["matchesHead"] is (file != THUMB), (label, file)
    assert r["matchesBefore"] is not (file == THUMB or (label in ("s89b", "s89c") and scheme)), (label, file)
# The driver opens files in name order (#671). Every PDF Word saved renders the main document's "Hello", the s89b
# calibrations their header's "Header 89" too, and the s89c used footer's calibration its "Footer 89".
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        assert [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()] == files, run
        for file in files:
            text = rendered(run, file)
            assert (text is None) is (results[(label, file)]["outcome"] != "clean-open"), (run, file)
            want = "Header 89 Hello" if file.startswith("header-image-") else "Hello Footer 89" if file == "sidecar-footer-used-plain-calibration.docx" else "Hello"
            assert text in (None, want), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}"
n = len(rows)
mb, ma = sum(r["matchesBefore"] for r in results.values()), sum(r["matchesHead"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 89: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {b} and {a}",
    "",
    f"The placements of a scheme-like internal target session 88 did not show Word ([#1184]({I}1184), raised by the "
    f"adversarial review of [#1182]({I}1182)). Every `ftp:` row stores the part the path spells well-formed, and each "
    "placement has a calibration through its plain name. Three chunks, on the minimal package.",
    "",
    "- **s89a.** `_rels/.rels` relates the core, extended (app) and custom properties and the thumbnail through "
    "`ftp:docProps/…`, stored `/ftp:docProps/…`. #1182 blocked these by extrapolation from s88a's styles row.",
    "- **s89b.** A used header's own sidecar (`word/_rels/header1.xml.rels`) relates an image through `ftp:image1.png`, "
    "stored `word/ftp:image1.png`, which the header either embeds through `r:embed` in an inline drawing or does not use. "
    "#1182 kept these a warning.",
    "- **s89c.** The same unused `ftp:image1.png` image in other sidecars: a used footer's, an unused header's, the "
    "styles part's and an unreferenced part's (`word/foo.xml`, which no relationship names).",
    "",
    "Each chunk ends with a minimal control. Each chunk ran twice, as two separate driver runs of byte-identical copies, "
    "and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by "
    f"`wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` "
    f"otherwise; {sum(r['agreed'] for r in results.values())} of {n} rows agree. The two times in Observed are the ends of "
    "the row's two runs. Shape is the builder's description of the specimen. The builder judged every row at "
    f"`{next(iter(before))}`, before the fix; `rejudge.mts` judged the same bytes at `{next(iter(after))}`. First "
    "attempts at s89a and s89c overlapped another session driving Word (its own `complex.docx` dialogs appear in the "
    "s89a one), so they were set aside unread, and every run here was taken with no other Word driver running.",
    "",
    "- **The `_rels/.rels` block holds for the properties parts.** Word offered recovery for the core, extended and "
    "custom properties through `ftp:`, and opened each plain calibration clean, as #1182 predicted.",
    "- **The thumbnail row shows nothing about the scheme.** Word offered recovery for its plain calibration too, a PNG "
    f"thumbnail at `docProps/thumbnail.png` typed by a `png` Default, which word-valid passes ([#1186]({I}1186)).",
    "- **A scheme target blocks in every relationships part Word was shown.** Word offered recovery for both s89b `ftp:` "
    "rows in a used header's sidecar, the embedded image and the unused one, and for all four s89c sidecars, and opened "
    "every calibration clean, rendering the header's `Header 89` and the used footer's `Footer 89`. Sessions 79 and 80 had "
    "opened a folder target in such sidecars clean, so only the scheme target extends there.",
    "- **Every control opened clean.** Every PDF Word saved renders the main document's `Hello` (`pdftotext`); no refused "
    "row left a PDF.",
    "",
    f"Word-valid at {b} matches Word on {mb} of {n} rows: it warned on the six s89b and s89c `ftp:` rows and passed the "
    f"thumbnail calibration. At {a} it matches on {ma} of {n}; the thumbnail calibration is #1186.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {b} | word-valid at {a} | strict at {a} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 89</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 89 builder, re-judge, cross-check and section scripts</summary>",
    "",
    "Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed "
    "tree at the first revision, and the re-judge from the root of the committed tree at the second.",
    "",
]
for name, path, lang in (("s89builder.mts", ROOT / "s89builder.mts", "ts"), ("rejudge.mts", ROOT / "s89/rejudge.mts", "ts"),
                         ("compare.py", ROOT / "s89/compare.py", "python"), ("section.py", ROOT / "s89/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s89/section.md").write_text("\n".join(out))
print(n, "rows,", len(raw), "raw records,", mb, "/", ma, "match")
`````

</details>

### Session 90: 19:42Z–19:45Z on 2026-10-30, validator columns at 2a98048d and dd43a20d

Why Word refused session 89's plain thumbnail calibration (s89a), a 1x1 PNG at `docProps/thumbnail.png` that `_rels/.rels` relates by the package thumbnail type and a `png` Default types ([#1186](https://github.com/jandira-tech/docx-validate/issues/1186)). One chunk, on the minimal package plus one thumbnail variant per row: that row again, the same bytes stored but related by nothing, a 96x96 PNG, the 1x1 PNG typed by an `Override`, and a 96x96 JPEG at `docProps/thumbnail.jpeg` typed `image/jpeg` by a Default and by an Override (the name and format Word for Mac writes). The 96x96 assets were made with `sips`.

The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 7 of 7 rows agree. The builder judged every row at `2a98048de47687f7424fb6925b6fc5d8f377e11f`, before the rule; `rejudge.mts` judged the same bytes at `dd43a20db1dc588c473a2e9b712311104b07e013`. The first attempt at the second run may have overlapped another session's Word driver, so it was set aside and repeated with none running; both second runs read alike.

- **Word refuses a PNG package thumbnail.** It offered recovery for the 1x1 and the 96x96 PNG, typed by a Default or by an Override.
- **It opens a JPEG one clean,** typed by a Default or by an Override, and the same PNG stored with no relationship naming it.
- **Every control opened clean,** and every PDF Word saved renders the main document's `Hello` (`pdftotext`).

Word-valid at 2a98048d matches Word on 4 of 7 rows: it passed the three related PNG rows. At dd43a20d the new `word-package-thumbnail-type` rule refuses them, and word-valid matches on 7 of 7, and on session 89's thumbnail calibration too.

| Run    | Observed             | Specimen                       | Shape                                                                                       | SHA-256 (first 16) | Word, run 1    | Word, run 2    | Outcome                    | word-valid at 2a98048d | word-valid at dd43a20d                                        | strict at dd43a20d                                            |
| ------ | -------------------- | ------------------------------ | ------------------------------------------------------------------------------------------- | ------------------ | -------------- | -------------- | -------------------------- | ---------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-png1-default-s89a`      | #1186: s89a's thumbnail calibration again: a 1x1 PNG at docProps/thumbnail.png, png Default | `6c086d771797abe4` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-png1-default-unrelated` | #1186: the same PNG and Default, but no relationship names the part                         | `635ebce8a431f217` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                         | invalid: `rels-unreferenced@docProps/thumbnail.png`           |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-png96-default`          | #1186: a 96x96 PNG at docProps/thumbnail.png, png Default                                   | `9d8118cab1c746c8` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-png1-override`          | #1186: the 1x1 PNG typed image/png by an Override                                           | `529bcf2e7cf6b8c0` | repair-warning | repair-warning | unreadable-content-warning | valid                  | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` | invalid: `word-package-thumbnail-type@docProps/thumbnail.png` |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-jpeg96-default`         | #1186: a 96x96 JPEG at docProps/thumbnail.jpeg, jpeg Default                                | `f1974c0c313089bc` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                         | valid                                                         |
| `s90a` | 19:42:35Z, 19:45:04Z | `thumb-jpeg96-override`        | #1186: the same JPEG typed image/jpeg by an Override                                        | `a44af1cb4f5e72c4` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                         | valid                                                         |
| `s90a` | 19:42:35Z, 19:45:04Z | `s90a-control-minimal`         | control                                                                                     | `52c5d69e80ae92ad` | clean-open     | clean-open     | clean-open                 | valid                  | valid                                                         | valid                                                         |

<details><summary>Raw records, session 90</summary>

```jsonl
{"run": "s90a", "pass": 1, "name": "thumb-png1-default-s89a", "sha256": "6c086d771797abe4535370e8a7f79094ecd809de0cb377175ec63dad5ab048f2", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00003__wfv__thumb-png1-default-s89a.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:24.969 'Word found unreadable content in 00003__wfv__thumb-png1-default-s89a.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:25.456 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__thumb-png1-default-s89a.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s90a", "pass": 2, "name": "thumb-png1-default-s89a", "sha256": "6c086d771797abe4535370e8a7f79094ecd809de0cb377175ec63dad5ab048f2", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00003__wfv__thumb-png1-default-s89a.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:44:02.782 'Word found unreadable content in 00003__wfv__thumb-png1-default-s89a.docx. Do you want to recover t … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:44:03.435 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi …  converter. (00003__wfv__thumb-png1-default-s89a.docx)\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00003__wfv__thumb-png1-default-s89a.docx; refusing to guess"}
{"run": "s90a", "pass": 1, "name": "thumb-png1-default-unrelated", "sha256": "635ebce8a431f217e3323c530ba977d5ae264d1c5b5245b21bcf633219e98695", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00004__wfv__thumb-png1-default-unrelated.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-png1-default-unrelated_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 2, "name": "thumb-png1-default-unrelated", "sha256": "635ebce8a431f217e3323c530ba977d5ae264d1c5b5245b21bcf633219e98695", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00004__wfv__thumb-png1-default-unrelated.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-png1-default-unrelated_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 1, "name": "thumb-png96-default", "sha256": "9d8118cab1c746c8b50e6a74150f96de9487cc62e28a5cdc6fd5969a4a090eb3", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00006__wfv__thumb-png96-default.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:33.863 'Word found unreadable content in 00006__wfv__thumb-png96-default.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:34.686 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00006__wfv__thumb-png96-default.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s90a", "pass": 2, "name": "thumb-png96-default", "sha256": "9d8118cab1c746c8b50e6a74150f96de9487cc62e28a5cdc6fd5969a4a090eb3", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00006__wfv__thumb-png96-default.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:45:03.934 Microsoft Word, Word found unreadable content in 00006__wfv__thumb-png96-default.docx. Do you want t … t? If you trust the source of this document, click Yes."], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00006__wfv__thumb-png96-default.docx; refusing to guess"}
{"run": "s90a", "pass": 1, "name": "thumb-png1-override", "sha256": "529bcf2e7cf6b8c01ee3b639a902e119f025a0eaea268abeb52c416b44fcb578", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00005__wfv__thumb-png1-override.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:42:29.550 'Word found unreadable content in 00005__wfv__thumb-png1-override.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.'", "2026-10-30 15:42:30.326 \"Word experienced an error trying to open the file. Try these suggestions. * Check the file permissi … very converter. (00005__wfv__thumb-png1-override.docx)\""], "error": "repair prompt declined; Word could not read it"}
{"run": "s90a", "pass": 2, "name": "thumb-png1-override", "sha256": "529bcf2e7cf6b8c01ee3b639a902e119f025a0eaea268abeb52c416b44fcb578", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00005__wfv__thumb-png1-override.docx", "logVerdict": "repair-warning", "tableVerdict": "repair-warning", "pdf": false, "evidence": ["2026-10-30 15:44:20.233 \"Word found unreadable content in 00005__wfv__thumb-png1-override.docx. Do you want to recover the c … ? If you trust the source of this document, click Yes.\""], "error": "repair prompt declined; Word could not read it: open produced 0 new documents, none named 00005__wfv__thumb-png1-override.docx; refusing to guess"}
{"run": "s90a", "pass": 1, "name": "thumb-jpeg96-default", "sha256": "f1974c0c313089bc1fa055639a159ecc65b8f9b002f8ea9608ac55269ef62ac8", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00001__wfv__thumb-jpeg96-default.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-jpeg96-default_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 2, "name": "thumb-jpeg96-default", "sha256": "f1974c0c313089bc1fa055639a159ecc65b8f9b002f8ea9608ac55269ef62ac8", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00001__wfv__thumb-jpeg96-default.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-jpeg96-default_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 1, "name": "thumb-jpeg96-override", "sha256": "a44af1cb4f5e72c44f62b3c07c908ce4e19390966f0487ffc4757fae49cd3cdd", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00002__wfv__thumb-jpeg96-override.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-jpeg96-override_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 2, "name": "thumb-jpeg96-override", "sha256": "a44af1cb4f5e72c44f62b3c07c908ce4e19390966f0487ffc4757fae49cd3cdd", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00002__wfv__thumb-jpeg96-override.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF thumb-jpeg96-override_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 1, "name": "s90a-control-minimal", "sha256": "52c5d69e80ae92add1d7e4f73af4645e4c85ff5ea0d5cd8d95ca3f375cf4a901", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:42:35+00:00", "staged": "00000__wfv__s90a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s90a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s90a", "pass": 2, "name": "s90a-control-minimal", "sha256": "52c5d69e80ae92add1d7e4f73af4645e4c85ff5ea0d5cd8d95ca3f375cf4a901", "validatorRevision": "2a98048de47687f7424fb6925b6fc5d8f377e11f", "observedAt": "2026-10-30T19:45:04+00:00", "staged": "00000__wfv__s90a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s90a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 90 builder, re-judge, cross-check and section scripts</summary>

Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed tree at the first revision, and the re-judge from the root of the committed tree at the second.

`s90builder.mts`:

```ts
// Session 90 (2026-10-30, #1186): why Word refused session 89's plain thumbnail calibration (s89a), a 1x1 PNG at
// docProps/thumbnail.png that _rels/.rels relates by the package thumbnail type and a png Default types. Every row is
// the minimal package (`tests/support/minimal-docx.ts`) plus one thumbnail variant.
// s90a: that s89a row again; the same bytes stored but related by nothing; a 96x96 PNG; the 1x1 PNG typed by an
//   Override instead of a Default; a 96x96 JPEG at docProps/thumbnail.jpeg typed by a jpeg Default (the name and
//   format Word for Mac writes); the same JPEG typed image/jpeg by an Override.
// Assets: s90/assets (1x1.png from s89a's bytes; 96.png and 96.jpeg made with sips).
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: CHUNK=s90a pnpm exec node --import tsx <abs path to this file>  (from the committed tree's root)
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const PKG_RELS = "_rels/.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const defaults = (ct: string, extension: string, type: string) =>
    replaceOnce(ct, '<Default Extension="xml"', `<Default Extension="${extension}" ContentType="${type}"/><Default Extension="xml"`);
/** `parts` with `r:` declared on the main document and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string | Uint8Array>, sect: string): Record<string, string | Uint8Array> => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
});

import { readFileSync } from "node:fs";
const PKG = "http://schemas.openxmlformats.org/package/2006/relationships";
const THUMB = `${PKG}/metadata/thumbnail`;
const asset = (name: string) => readFileSync(path.join(ROOT, "s90", "assets", name));
type Variant = { file: string; bytes: Uint8Array; type: string; by: "default" | "override"; related?: boolean };
const thumbnail = (v: Variant) => {
    const ext = v.file.slice(v.file.lastIndexOf(".") + 1);
    return {
        ...P,
        [`docProps/${v.file}`]: v.bytes,
        [PKG_RELS]:
            v.related === false
                ? P[PKG_RELS]!
                : appendRels(P[PKG_RELS]!, `<Relationship Id="rIdT" Type="${THUMB}" Target="docProps/${v.file}"/>`),
        [CT]: v.by === "default" ? defaults(P[CT]!, ext, v.type) : overrides(P[CT]!, [`docProps/${v.file}`, v.type]),
    };
};
type Row = [string, string, () => Promise<Uint8Array>];
const row = (name: string, issue: string, v: Variant): Row => [name, issue, () => buildDocx(thumbnail(v))];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s90a: withControl("s90a", [
        row("thumb-png1-default-s89a", "#1186: s89a's thumbnail calibration again: a 1x1 PNG at docProps/thumbnail.png, png Default", {
            file: "thumbnail.png",
            bytes: asset("1x1.png"),
            type: "image/png",
            by: "default",
        }),
        row("thumb-png1-default-unrelated", "#1186: the same PNG and Default, but no relationship names the part", {
            file: "thumbnail.png",
            bytes: asset("1x1.png"),
            type: "image/png",
            by: "default",
            related: false,
        }),
        row("thumb-png96-default", "#1186: a 96x96 PNG at docProps/thumbnail.png, png Default", {
            file: "thumbnail.png",
            bytes: asset("96.png"),
            type: "image/png",
            by: "default",
        }),
        row("thumb-png1-override", "#1186: the 1x1 PNG typed image/png by an Override", {
            file: "thumbnail.png",
            bytes: asset("1x1.png"),
            type: "image/png",
            by: "override",
        }),
        row("thumb-jpeg96-default", "#1186: a 96x96 JPEG at docProps/thumbnail.jpeg, jpeg Default", {
            file: "thumbnail.jpeg",
            bytes: asset("96.jpeg"),
            type: "image/jpeg",
            by: "default",
        }),
        row("thumb-jpeg96-override", "#1186: the same JPEG typed image/jpeg by an Override", {
            file: "thumbnail.jpeg",
            bytes: asset("96.jpeg"),
            type: "image/jpeg",
            by: "override",
        }),
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
            warnings: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "warning")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`], warnings: [] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} warn=${row.wordValid.warnings.filter((w: string) => w.startsWith("rels")).join(",")} strict=${row.strict.valid}`,
    );
}
```

`rejudge.mts`:

```ts
// Judge the bytes session 90 showed Word (each chunk's src/) with the validator in WT, and record its revision per row.
// Run: WT=<tree> tsx <abs path to this file>
import { execFileSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(path.dirname(new URL(import.meta.url).pathname));
const WT = process.env.WT ?? process.cwd();
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const verdict = async (file: string, profile: "word-valid" | "strict") => {
    const r = await validate(file, { profile });
    return {
        valid: r.valid,
        errors: [
            ...new Set(
                r.issues
                    .filter((x: { severity: string }) => x.severity === "error")
                    .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
            ),
        ],
    };
};
const out: string[] = [];
for (const chunk of ["s90a"]) {
    for (const line of readFileSync(path.join(ROOT, chunk, "specimens.jsonl"), "utf8")
        .trim()
        .split("\n")) {
        const spec = JSON.parse(line);
        const file = path.join(ROOT, chunk, "src", spec.file);
        out.push(
            JSON.stringify({
                chunk,
                file: spec.file,
                validatorRevision: REVISION,
                wordValid: await verdict(file, "word-valid"),
                strict: await verdict(file, "strict"),
            }),
        );
    }
}
writeFileSync(path.join(ROOT, "s90", "rejudge.jsonl"), out.join("\n") + "\n");
console.log(out.length, "rows at", REVISION);
```

`compare.py`:

```python
"""Join the two runs of the session-90 chunks: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are its chunk's first pass (the chunk folder) and second pass (`pass2`), separate driver runs of
byte-identical copies. The validator verdicts come from the builder (`specimens.jsonl`, judged before the fixes) and
from `rejudge.jsonl` (the same bytes judged at the branch head).
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s90a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s90/rejudge.jsonl").read_text().splitlines())}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def matches(readings, valid):
    return (all(r in REJECTIONS for r in readings) and valid is False) or (all(r == "clean-open" for r in readings) and valid is True)


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    runs = [ROOT / label, ROOT / label / "pass2"]
    for name, spec in specs.items():
        for run in runs:
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        at_head = head[(label, name)]
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "readings": readings, "agreed": agreed, "outcome": TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown",
                     "wordValidBefore": spec["wordValid"]["valid"], "wordValidHead": at_head["wordValid"]["valid"],
                     "headRevision": at_head["validatorRevision"],
                     "matchesBefore": agreed and matches(readings, spec["wordValid"]["valid"]),
                     "matchesHead": agreed and matches(readings, at_head["wordValid"]["valid"])})
(ROOT / "s90/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<40} {r['outcome']:<27} before={r['wordValidBefore']!s:<5} head={r['wordValidHead']!s:<5} match={r['matchesBefore']}/{r['matchesHead']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| matches before:", sum(r["matchesBefore"] for r in rows),
      "| at head:", sum(r["matchesHead"] for r in rows))
```

`section.py`:

`````python
"""Render the session-90 part of docs/plans/evidence/word-probes-2026-10-24.md into s89/section.md.

Reads each chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, rejudge.jsonl (the same bytes judged at the branch head) and the
results.json compare.py writes. Revisions come from the rows, never from this script. The text Word rendered is read
from its own PDFs with pdftotext, so the narrative's "rendered" claim is checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s90a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s90/results.json").read_text())}
head = {(r["chunk"], r["file"]): r for r in map(json.loads, (ROOT / "s90/rejudge.jsonl").read_text().splitlines())}


def cell(v):
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" if v["valid"] else "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, before, after = [], [], [], [], set(), set()
for label in CHUNKS:
    for s in map(json.loads, (ROOT / label / "specimens.jsonl").read_text().splitlines()):
        result, h = results[(label, s["file"])], head[(label, s["file"])]
        runs = [ROOT / label, ROOT / label / "pass2"]
        before.add(s["validatorRevision"])
        after.add(h["validatorRevision"])
        times = [datetime.fromisoformat(manifest(r, s["file"])["run_at"]).astimezone(timezone.utc) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        cs = [checks(r)[s["file"]] for r in runs]
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {s['issue'].replace('|', chr(92) + '|')} | "
            f"`{s['sha256'][:16]}` | {word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | {cell(s['wordValid'])} | "
            f"{cell(h['wordValid'])} | {cell(h['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, cs, times), start=1):
            out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s["validatorRevision"],
                   "observedAt": t.isoformat(), "staged": c["staged"], "logVerdict": c["logVerdict"], "tableVerdict": c["outcomesVerdict"],
                   "pdf": c["pdf"], "evidence": c["evidence"]}
            if manifest(r, s["file"]).get("error"):
                out["error"] = manifest(r, s["file"])["error"]
            raw.append(json.dumps(out, ensure_ascii=False))

assert len(before) == 1 and len(after) == 1, (before, after)
b, a = next(iter(before))[:8], next(iter(after))[:8]
# The narrative's claims, checked against results.json: every row's four readings agree; Word offered recovery for
# exactly the three related PNG rows and opened the rest clean; word-valid at the head matches Word on every row, and
# before the rule it missed exactly those three.
PNG_RELATED = {"thumb-png1-default-s89a.docx", "thumb-png96-default.docx", "thumb-png1-override.docx"}
for (label, file), r in results.items():
    assert r["agreed"], (label, file)
    assert r["outcome"] == ("unreadable-content-warning" if file in PNG_RELATED else "clean-open"), (label, file, r["outcome"])
    assert r["matchesHead"], (label, file)
    assert r["matchesBefore"] is not (file in PNG_RELATED), (label, file)
# The driver opens files in name order (#671). Every PDF Word saved renders the main document's "Hello".
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        assert [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()] == files, run
        for file in files:
            text = rendered(run, file)
            assert (text is None) is (results[(label, file)]["outcome"] != "clean-open"), (run, file)
            assert text in (None, "Hello"), (run, file, text)
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}"
n = len(rows)
mb, ma = sum(r["matchesBefore"] for r in results.values()), sum(r["matchesHead"] for r in results.values())
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 90: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {b} and {a}",
    "",
    f"Why Word refused session 89's plain thumbnail calibration (s89a), a 1x1 PNG at `docProps/thumbnail.png` that "
    f"`_rels/.rels` relates by the package thumbnail type and a `png` Default types ([#1186]({I}1186)). One chunk, on the "
    "minimal package plus one thumbnail variant per row: that row again, the same bytes stored but related by nothing, a "
    "96x96 PNG, the 1x1 PNG typed by an `Override`, and a 96x96 JPEG at `docProps/thumbnail.jpeg` typed `image/jpeg` by a "
    "Default and by an Override (the name and format Word for Mac writes). The 96x96 assets were made with `sips`.",
    "",
    "The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    f"is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{sum(r['agreed'] for r in results.values())} of {n} rows agree. The builder judged every row at "
    f"`{next(iter(before))}`, before the rule; `rejudge.mts` judged the same bytes at `{next(iter(after))}`. The first "
    "attempt at the second run may have overlapped another session's Word driver, so it was set aside and repeated with "
    "none running; both second runs read alike.",
    "",
    "- **Word refuses a PNG package thumbnail.** It offered recovery for the 1x1 and the 96x96 PNG, typed by a Default or "
    "by an Override.",
    "- **It opens a JPEG one clean,** typed by a Default or by an Override, and the same PNG stored with no relationship "
    "naming it.",
    "- **Every control opened clean,** and every PDF Word saved renders the main document's `Hello` (`pdftotext`).",
    "",
    f"Word-valid at {b} matches Word on {mb} of {n} rows: it passed the three related PNG rows. At {a} the new "
    f"`word-package-thumbnail-type` rule refuses them, and word-valid matches on {ma} of {n}, and on session 89's thumbnail "
    "calibration too.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | word-valid at {b} | word-valid at {a} | strict at {a} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 90</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 90 builder, re-judge, cross-check and section scripts</summary>",
    "",
    "Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of the committed "
    "tree at the first revision, and the re-judge from the root of the committed tree at the second.",
    "",
]
for name, path, lang in (("s90builder.mts", ROOT / "s90builder.mts", "ts"), ("rejudge.mts", ROOT / "s90/rejudge.mts", "ts"),
                         ("compare.py", ROOT / "s90/compare.py", "python"), ("section.py", ROOT / "s90/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s90/section.md").write_text("\n".join(out))
print(n, "rows,", len(raw), "raw records,", mb, "/", ma, "match")
`````

</details>

### Session 91: 22:42Z–22:47Z on 2026-10-30, validator columns at 1d88dab4

The three shapes the malformation audit found unjudged ([#1212](https://github.com/jandira-tech/docx-validate/issues/1212)), which #1213's `word-field-unbalanced`, `word-move-range-unpaired` and `xml-package-markup-compatibility` report as word-valid warnings and strict errors. One chunk, on the minimal package with its one run replaced or one part added: a body field with only a `begin` `w:fldChar`, one with `begin`, a `PAGE` instruction and `separate` but no `end`, an orphan `end`, and a balanced `PAGE` field calibration; a move-from range named `a` with no move-to range, a move-from start with no end beside its move-to pair, and a paired move calibration; and a `customXml/item1.xml` the main document relates whose `mc:Choice` `Requires` an undeclared prefix, with a calibration declaring it.

The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; 10 of 10 rows agree. The builder judged every row at `1d88dab4a6141f744b8698d0f1f51ff03cc668fe`, the #1213 head. Both runs waited until no other session's Word driver had run for 90 s.

- **Word opens every shape clean.** No dialog named any row, in either run.
- **It renders the broken fields as plain text.** The calibration's `PAGE` field computed `1`; the field with no `end` rendered its instruction, `PAGE`, before the text, and the `begin`-only and orphan-`end` rows rendered the text alone.
- **It renders both sides of a move,** paired or not: the calibration and the start with no end show `HelloHello`, and the unpaired move-from shows its text.

Word-valid at 1d88dab4 matches Word on 10 of 10 rows: it passes every row and warns on the six defective ones. Strict refuses those six, as its profile intends.

| Run    | Observed             | Specimen                                  | Shape                                                                      | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome    | Word rendered | word-valid at 1d88dab4                   | strict at 1d88dab4                                    |
| ------ | -------------------- | ----------------------------------------- | -------------------------------------------------------------------------- | ------------------ | ----------- | ----------- | ---------- | ------------- | ---------------------------------------- | ----------------------------------------------------- |
| `s91a` | 22:42:09Z, 22:47:19Z | `field-begin-only`                        | #1212: a body fldChar begin with no separate or end                        | `f56376b7742fd910` | clean-open  | clean-open  | clean-open | `Hello`       | valid (warns `word-field-unbalanced`)    | invalid: `word-field-unbalanced@word/document.xml`    |
| `s91a` | 22:42:09Z, 22:47:19Z | `field-begin-separate-no-end`             | #1212: begin, PAGE instrText and separate, with no end                     | `481b31d1dadcddb4` | clean-open  | clean-open  | clean-open | `PAGE Hello`  | valid (warns `word-field-unbalanced`)    | invalid: `word-field-unbalanced@word/document.xml`    |
| `s91a` | 22:42:09Z, 22:47:19Z | `field-end-orphan`                        | #1212: a fldChar end with no begin                                         | `f8fe0ea3876db385` | clean-open  | clean-open  | clean-open | `Hello`       | valid (warns `word-field-unbalanced`)    | invalid: `word-field-unbalanced@word/document.xml`    |
| `s91a` | 22:42:09Z, 22:47:19Z | `field-page-calibration`                  | #1212: a balanced PAGE field                                               | `67775e8b421c5ca6` | clean-open  | clean-open  | clean-open | `1`           | valid                                    | valid                                                 |
| `s91a` | 22:42:09Z, 22:47:19Z | `move-from-unpaired`                      | #1212: a move-from range named a, with no move-to range                    | `0adb27757ef043a9` | clean-open  | clean-open  | clean-open | `Hello`       | valid (warns `word-move-range-unpaired`) | invalid: `word-move-range-unpaired@word/document.xml` |
| `s91a` | 22:42:09Z, 22:47:19Z | `move-from-start-no-end`                  | #1212: a moveFromRangeStart with no moveFromRangeEnd, and its move-to pair | `db5a14766af0a7df` | clean-open  | clean-open  | clean-open | `HelloHello`  | valid (warns `word-move-range-unpaired`) | invalid: `word-move-range-unpaired@word/document.xml` |
| `s91a` | 22:42:09Z, 22:47:19Z | `move-pair-calibration`                   | #1212: a move-from and a move-to range both named a                        | `1c7dd202f37df75d` | clean-open  | clean-open  | clean-open | `HelloHello`  | valid                                    | valid                                                 |
| `s91a` | 22:42:09Z, 22:47:19Z | `customxml-requires-undeclared`           | #1212: a related customXml item whose Choice Requires an undeclared prefix | `4f65bbcbe60d9ea0` | clean-open  | clean-open  | clean-open | `Hello`       | valid (warns `mce-malformed`)            | invalid: `mce-malformed@customXml/item1.xml`          |
| `s91a` | 22:42:09Z, 22:47:19Z | `customxml-requires-declared-calibration` | #1212: the same item with the Requires prefix declared                     | `dcef4c0cd97d0751` | clean-open  | clean-open  | clean-open | `Hello`       | valid                                    | valid                                                 |
| `s91a` | 22:42:09Z, 22:47:19Z | `s91a-control-minimal`                    | control                                                                    | `96735acbb658e2d4` | clean-open  | clean-open  | clean-open | `Hello`       | valid                                    | valid                                                 |

<details><summary>Raw records, session 91</summary>

```jsonl
{"run": "s91a", "pass": 1, "name": "field-begin-only", "sha256": "f56376b7742fd910472f6b989d3353bf54457cb9170cf36ab6ee18a1ba692da5", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00002__wfv__field-begin-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-begin-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "field-begin-only", "sha256": "f56376b7742fd910472f6b989d3353bf54457cb9170cf36ab6ee18a1ba692da5", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00002__wfv__field-begin-only.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-begin-only_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "field-begin-separate-no-end", "sha256": "481b31d1dadcddb4b3ab85937bf4226815422762f4feee61528d04bdcb704a73", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00003__wfv__field-begin-separate-no-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-begin-separate-no-end_byword.pdf (15419 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "field-begin-separate-no-end", "sha256": "481b31d1dadcddb4b3ab85937bf4226815422762f4feee61528d04bdcb704a73", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00003__wfv__field-begin-separate-no-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-begin-separate-no-end_byword.pdf (15419 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "field-end-orphan", "sha256": "f8fe0ea3876db3856e688886bfcba0eebb05fd42332b0945995a48e6874de06d", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00004__wfv__field-end-orphan.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-end-orphan_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "field-end-orphan", "sha256": "f8fe0ea3876db3856e688886bfcba0eebb05fd42332b0945995a48e6874de06d", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00004__wfv__field-end-orphan.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-end-orphan_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "field-page-calibration", "sha256": "67775e8b421c5ca66f950c6b7ec18fefe9b93a90071f537866efc5fd9716f8cd", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00005__wfv__field-page-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-page-calibration_byword.pdf (11342 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "field-page-calibration", "sha256": "67775e8b421c5ca66f950c6b7ec18fefe9b93a90071f537866efc5fd9716f8cd", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00005__wfv__field-page-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF field-page-calibration_byword.pdf (11342 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "move-from-unpaired", "sha256": "0adb27757ef043a9e4a57434df42d6e2b31ac3437e0a05b493f9b1833458ad1e", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00007__wfv__move-from-unpaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-unpaired_byword.pdf (13454 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "move-from-unpaired", "sha256": "0adb27757ef043a9e4a57434df42d6e2b31ac3437e0a05b493f9b1833458ad1e", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00007__wfv__move-from-unpaired.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-unpaired_byword.pdf (13454 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "move-from-start-no-end", "sha256": "db5a14766af0a7dfb1451713a760ed0b54ee31c236417b0b513a0f60b463d01e", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00006__wfv__move-from-start-no-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-start-no-end_byword.pdf (13494 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "move-from-start-no-end", "sha256": "db5a14766af0a7dfb1451713a760ed0b54ee31c236417b0b513a0f60b463d01e", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00006__wfv__move-from-start-no-end.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-from-start-no-end_byword.pdf (13494 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "move-pair-calibration", "sha256": "1c7dd202f37df75da111a342788c6f507043ca78d1af2be2d23545a1df2a4a79", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00008__wfv__move-pair-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-pair-calibration_byword.pdf (13526 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "move-pair-calibration", "sha256": "1c7dd202f37df75da111a342788c6f507043ca78d1af2be2d23545a1df2a4a79", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00008__wfv__move-pair-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF move-pair-calibration_byword.pdf (13526 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "customxml-requires-undeclared", "sha256": "4f65bbcbe60d9ea0b792fc6117ca5023d02d6279b227881f86c879b7e27ed6c0", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00001__wfv__customxml-requires-undeclared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-requires-undeclared_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "customxml-requires-undeclared", "sha256": "4f65bbcbe60d9ea0b792fc6117ca5023d02d6279b227881f86c879b7e27ed6c0", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00001__wfv__customxml-requires-undeclared.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-requires-undeclared_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "customxml-requires-declared-calibration", "sha256": "dcef4c0cd97d0751f08f598101e7d3c29202e63dea06de79f0a1232b6053f049", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00000__wfv__customxml-requires-declared-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-requires-declared-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "customxml-requires-declared-calibration", "sha256": "dcef4c0cd97d0751f08f598101e7d3c29202e63dea06de79f0a1232b6053f049", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00000__wfv__customxml-requires-declared-calibration.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF customxml-requires-declared-calibration_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 1, "name": "s91a-control-minimal", "sha256": "96735acbb658e2d4a4b0f0700fdc39ff65e7775396bfff4c022532b5d0dfd5d0", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:42:09+00:00", "staged": "00009__wfv__s91a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s91a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
{"run": "s91a", "pass": 2, "name": "s91a-control-minimal", "sha256": "96735acbb658e2d4a4b0f0700fdc39ff65e7775396bfff4c022532b5d0dfd5d0", "validatorRevision": "1d88dab4a6141f744b8698d0f1f51ff03cc668fe", "observedAt": "2026-10-30T22:47:19+00:00", "staged": "00009__wfv__s91a-control-minimal.docx", "logVerdict": "clean-open", "tableVerdict": "clean-open", "pdf": true, "evidence": ["PDF s91a-control-minimal_byword.pdf (13382 bytes), no dialog named the file"]}
```

</details>

<details><summary>Session 91 builder, cross-check and section scripts</summary>

Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of a clean checkout of the committed tree; its refusal of a tree with uncommitted changes (CodeRabbit on #1182) was added after the build, and is the only change since.

`s91builder.mts`:

```ts
// Session 91 (2026-10-30, #1212): the field, move-range and customXml compatibility shapes #1213 warns on. Every row is
// the minimal package (`tests/support/minimal-docx.ts`) with one paragraph run replaced, or one customXml part added.
// s91a: an unclosed field (begin only; begin, instrText and separate), an orphan end, and a balanced PAGE field
//   calibration; a move-from range with no move-to range, a move-from start with no end, and a paired move calibration;
//   a customXml item whose Choice Requires an undeclared prefix, and the same item with the prefix declared.
// Every chunk ends with a minimal control. Every row records the validator revision it was judged at
// (`validatorRevision`, `git -C <tree> rev-parse HEAD`).
// Run: CHUNK=s91a pnpm exec node --import tsx <abs path to this file>  (from the committed tree's root)
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { appendFileSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import path from "node:path";

const ROOT = path.dirname(new URL(import.meta.url).pathname);
const WT = process.env.WT ?? process.cwd();
// The recorded revision must name the bytes that judged the rows (CodeRabbit on #1182).
if (execFileSync("git", ["-C", WT, "status", "--porcelain", "--untracked-files=no"], { encoding: "utf8" }).trim() !== "")
    throw new Error(`${WT} has uncommitted changes`);
const { validate } = await import(path.join(WT, "src/scripts/office/validate.ts"));
const { MINIMAL_PARTS, buildDocx } = await import(path.join(WT, "tests/support/minimal-docx.ts"));
const REVISION = execFileSync("git", ["-C", WT, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();

const WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
const CT = "[Content_Types].xml";
const MAIN = "word/document.xml";
const SIDECAR = "word/_rels/document.xml.rels";
const PKG_RELS = "_rels/.rels";
const XML_DECL = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n`;
const R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const P = MINIMAL_PARTS as Record<string, string>;

const replaceOnce = (text: string, from: string, to: string) => {
    if (text.split(from).length !== 2) throw new Error(`expected exactly one ${from}`);
    return text.replace(from, to);
};
const relationship = (id: string, segment: string, target: string) =>
    `<Relationship Id="${id}" Type="${R}/${segment}" Target="${target}"/>`;
const appendRels = (rels: string, extra: string) => replaceOnce(rels, "</Relationships>", `${extra}</Relationships>`);
const overrides = (ct: string, ...entries: Array<[string, string]>) =>
    replaceOnce(
        ct,
        "</Types>",
        `${entries.map(([part, type]) => `<Override PartName="/${part}" ContentType="${type}"/>`).join("")}</Types>`,
    );
const defaults = (ct: string, extension: string, type: string) =>
    replaceOnce(ct, '<Default Extension="xml"', `<Default Extension="${extension}" ContentType="${type}"/><Default Extension="xml"`);
/** `parts` with `r:` declared on the main document and `sect` first in its w:sectPr. */
const mainWith = (parts: Record<string, string | Uint8Array>, sect: string): Record<string, string | Uint8Array> => ({
    ...parts,
    [MAIN]: replaceOnce(replaceOnce(P[MAIN]!, `xmlns:w="${W}"`, `xmlns:w="${W}" xmlns:r="${R}"`), "<w:sectPr>", `<w:sectPr>${sect}`),
});

const DATE = 'w:author="Probe" w:date="2026-10-30T00:00:00Z"';
const HELLO = "<w:r><w:t>Hello</w:t></w:r>";
const body = (runs: string) => ({ ...P, [MAIN]: replaceOnce(P[MAIN]!, HELLO, runs) });
const fld = (type: string) => `<w:r><w:fldChar w:fldCharType="${type}"/></w:r>`;
const instr = '<w:r><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r>';
const moveFrom = (name: string, end = true) =>
    `<w:moveFromRangeStart w:id="10" w:name="${name}" ${DATE}/><w:moveFrom w:id="11" ${DATE}>${HELLO}</w:moveFrom>${end ? '<w:moveFromRangeEnd w:id="10"/>' : ""}`;
const moveTo = (name: string) =>
    `<w:moveToRangeStart w:id="12" w:name="${name}" ${DATE}/><w:moveTo w:id="13" ${DATE}>${HELLO}</w:moveTo><w:moveToRangeEnd w:id="12"/>`;
const MCNS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
const customXml = (declare: boolean) => ({
    ...P,
    "customXml/item1.xml": `${XML_DECL}<x:root xmlns:x="urn:probe" xmlns:mc="${MCNS}"${declare ? ' xmlns:missing="urn:probe-missing"' : ""}><mc:AlternateContent><mc:Choice Requires="missing"><x:child/></mc:Choice><mc:Fallback/></mc:AlternateContent></x:root>`,
    [SIDECAR]: appendRels(P[SIDECAR]!, relationship("rIdC", "customXml", "../customXml/item1.xml")),
});
type Row = [string, string, () => Promise<Uint8Array>];
const row = (name: string, issue: string, parts: Record<string, string | Uint8Array>): Row => [name, issue, () => buildDocx(parts)];
const withControl = (chunk: string, rows: Row[]): Row[] => [...rows, [`${chunk}-control-minimal`, "control", () => buildDocx({ ...P })]];
const chunks: Record<string, Row[]> = {
    s91a: withControl("s91a", [
        row("field-begin-only", "#1212: a body fldChar begin with no separate or end", body(fld("begin") + HELLO)),
        row(
            "field-begin-separate-no-end",
            "#1212: begin, PAGE instrText and separate, with no end",
            body(fld("begin") + instr + fld("separate") + HELLO),
        ),
        row("field-end-orphan", "#1212: a fldChar end with no begin", body(HELLO + fld("end"))),
        row("field-page-calibration", "#1212: a balanced PAGE field", body(fld("begin") + instr + fld("separate") + HELLO + fld("end"))),
        row("move-from-unpaired", "#1212: a move-from range named a, with no move-to range", body(moveFrom("a"))),
        row(
            "move-from-start-no-end",
            "#1212: a moveFromRangeStart with no moveFromRangeEnd, and its move-to pair",
            body(moveFrom("a", false) + moveTo("a")),
        ),
        row("move-pair-calibration", "#1212: a move-from and a move-to range both named a", body(moveFrom("a") + moveTo("a"))),
        row(
            "customxml-requires-undeclared",
            "#1212: a related customXml item whose Choice Requires an undeclared prefix",
            customXml(false),
        ),
        row("customxml-requires-declared-calibration", "#1212: the same item with the Requires prefix declared", customXml(true)),
    ]),
};

const chunk = process.env.CHUNK ?? "";
const specimens = chunks[chunk];
if (!specimens) throw new Error(`CHUNK must be one of ${Object.keys(chunks).join(", ")}`);
const dir = path.join(ROOT, chunk, "src");
// A rerun starts from an empty src, so a removed or renamed row leaves no stale specimen (CodeRabbit on #985).
rmSync(dir, { recursive: true, force: true });
mkdirSync(dir, { recursive: true });
const jsonl = path.join(ROOT, chunk, "specimens.jsonl");
writeFileSync(jsonl, "");

const verdict = async (file: string, profile: "word-valid" | "strict") => {
    try {
        const r = await validate(file, { profile });
        return {
            valid: r.valid,
            errors: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "error")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
            warnings: [
                ...new Set(
                    r.issues
                        .filter((x: { severity: string }) => x.severity === "warning")
                        .map((x: { code: string; path?: string }) => `${x.code}@${x.path ?? "-"}`),
                ),
            ],
        };
    } catch (error) {
        return { valid: null, errors: [`threw:${(error as Error).name}:${(error as Error).message.slice(0, 80)}`], warnings: [] };
    }
};

for (const [name, issue, make] of specimens) {
    const bytes = await make();
    const file = `${name}.docx`;
    writeFileSync(path.join(dir, file), bytes);
    const sha256 = createHash("sha256").update(bytes).digest("hex");
    const target = path.join(dir, file);
    const row = {
        name,
        issue,
        file,
        sha256,
        calibration: name.includes("calibration"),
        control: issue === "control",
        validatorRevision: REVISION,
        wordValid: await verdict(target, "word-valid"),
        strict: await verdict(target, "strict"),
    };
    appendFileSync(jsonl, JSON.stringify(row) + "\n");
    console.log(
        `built ${file} ${sha256.slice(0, 16)} word-valid=${row.wordValid.valid} ${row.wordValid.errors.join(",")} warn=${row.wordValid.warnings.filter((w: string) => !w.startsWith("ct-")).join(",")} strict=${row.strict.valid}`,
    );
}
```

`compare.py`:

```python
"""Join the two runs of the session-91 chunk: log verdicts, table verdicts, validator verdicts, hashes.

Each row's runs are the chunk's first pass (the chunk folder) and second pass (`pass2`), separate driver runs of
byte-identical copies. The validator verdicts come from the builder (`specimens.jsonl`), which judged every row at the
#1213 head that adds the checks these shapes probe; there is no re-judge.
"""
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s91a",)
TO_MANIFEST = {"clean-open": "clean-open", "repair-warning": "unreadable-content-warning", "open-error": "open-error"}
REJECTIONS = {"repair-warning", "open-error"}


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def matches(readings, valid):
    return (all(r in REJECTIONS for r in readings) and valid is False) or (all(r == "clean-open" for r in readings) and valid is True)


rows = []
for label in CHUNKS:
    specs = {json.loads(l)["file"]: json.loads(l) for l in (ROOT / label / "specimens.jsonl").read_text().splitlines()}
    runs = [ROOT / label, ROOT / label / "pass2"]
    for name, spec in specs.items():
        for run in runs:
            digest = hashlib.sha256((run / "src" / name).read_bytes()).hexdigest()
            assert digest == spec["sha256"], f"{run}/{name}: {digest} != {spec['sha256']}"
        p1, p2 = (checks(run)[name] for run in runs)
        readings = [p1["logVerdict"], p1["outcomesVerdict"], p2["logVerdict"], p2["outcomesVerdict"]]
        agreed = len(set(readings)) == 1 and not p1["conflict"] and not p2["conflict"]
        rows.append({"chunk": label, "file": name, "sha256": spec["sha256"], "runs": [str(r.relative_to(ROOT)) for r in runs],
                     "readings": readings, "agreed": agreed, "outcome": TO_MANIFEST.get(readings[0], "unknown") if agreed else "unknown",
                     "wordValid": spec["wordValid"]["valid"], "revision": spec["validatorRevision"],
                     "matches": agreed and matches(readings, spec["wordValid"]["valid"])})
(ROOT / "s91/results.json").write_text(json.dumps(rows, indent=2) + "\n")
for r in rows:
    print(f"{r['chunk']} {r['file']:<45} {r['outcome']:<27} word-valid={r['wordValid']!s:<5} match={r['matches']}")
print("agreed:", sum(r["agreed"] for r in rows), "/", len(rows), "| matches:", sum(r["matches"] for r in rows))
```

`section.py`:

`````python
"""Render the session-91 part of docs/plans/evidence/word-probes-2026-10-24.md into s91/section.md.

Reads the chunk's specimens.jsonl (written by the builder, each row carrying the validator revision it was judged at),
each run's logcheck.jsonl and pdf/manifest.jsonl, and the results.json compare.py writes. Revisions come from the rows,
never from this script. The text Word rendered is read from its own PDFs with pdftotext, so the narrative's claims about
what Word rendered are checked here.
"""
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHUNKS = ("s91a",)
results = {(r["chunk"], r["file"]): r for r in json.loads((ROOT / "s91/results.json").read_text())}


def cell(v):
    if v["valid"] is None:
        return "threw: " + ", ".join(f"`{e}`" for e in v["errors"])
    if not v["valid"]:
        return "invalid: " + ", ".join(f"`{e}`" for e in v["errors"])
    return "valid" + (" (warns " + ", ".join(f"`{w.split('@')[0]}`" for w in v["warnings"]) + ")" if v["warnings"] else "")


def manifest(run, file):
    for line in (run / "pdf/manifest.jsonl").read_text().splitlines():
        row = json.loads(line)
        if row["original_filename"] == file:
            return row
    raise KeyError(file)


def checks(run):
    return {json.loads(l)["file"]: json.loads(l) for l in (run / "logcheck.jsonl").read_text().splitlines()}


def word_cell(check):
    log, table = check["logVerdict"], check["outcomesVerdict"]
    return log if log == table else f"log: {log}; table: {table}"


def rendered(run, file):
    pdf = run / "pdf" / (Path(file).stem + "_byword.pdf")
    if not pdf.exists():
        return None
    return " ".join(subprocess.run(["pdftotext", str(pdf), "-"], check=True, capture_output=True, text=True).stdout.split())


rows, raw, starts, ends, revisions = [], [], [], [], set()
texts = {}
for label in CHUNKS:
    for s in map(json.loads, (ROOT / label / "specimens.jsonl").read_text().splitlines()):
        result = results[(label, s["file"])]
        runs = [ROOT / label, ROOT / label / "pass2"]
        revisions.add(s["validatorRevision"])
        times = [datetime.fromisoformat(manifest(r, s["file"])["run_at"]).astimezone(timezone.utc) for r in runs]
        starts.append(times[0])
        ends.append(times[1])
        cs = [checks(r)[s["file"]] for r in runs]
        seen = {rendered(r, s["file"]) for r in runs}
        assert len(seen) == 1, (s["file"], seen)
        texts[s["file"]] = next(iter(seen))
        rows.append(
            f"| `{label}` | {times[0]:%H:%M:%S}Z, {times[1]:%H:%M:%S}Z | `{s['name']}` | {s['issue'].replace('|', chr(92) + '|')} | "
            f"`{s['sha256'][:16]}` | {word_cell(cs[0])} | {word_cell(cs[1])} | {result['outcome']} | `{texts[s['file']]}` | "
            f"{cell(s['wordValid'])} | {cell(s['strict'])} |"
        )
        for n, (r, c, t) in enumerate(zip(runs, cs, times), start=1):
            out = {"run": label, "pass": n, "name": s["name"], "sha256": s["sha256"], "validatorRevision": s["validatorRevision"],
                   "observedAt": t.isoformat(), "staged": c["staged"], "logVerdict": c["logVerdict"], "tableVerdict": c["outcomesVerdict"],
                   "pdf": c["pdf"], "evidence": c["evidence"]}
            if manifest(r, s["file"]).get("error"):
                out["error"] = manifest(r, s["file"])["error"]
            raw.append(json.dumps(out, ensure_ascii=False))

assert len(revisions) == 1, revisions
rev = next(iter(revisions))
# The narrative's claims, checked against results.json and the PDFs: every row's four readings agree and every row
# opened clean, so word-valid (which only warns on these shapes) matches Word on every row; the rendered texts are the
# ones the narrative quotes.
for (label, file), r in results.items():
    assert r["agreed"] and r["outcome"] == "clean-open" and r["matches"], (label, file, r)
assert texts["field-page-calibration.docx"] == "1"
assert texts["field-begin-separate-no-end.docx"] == "PAGE Hello"
assert texts["move-pair-calibration.docx"] == texts["move-from-start-no-end.docx"] == "HelloHello"
assert {f: t for f, t in texts.items() if t != "Hello"}.keys() == {"field-page-calibration.docx", "field-begin-separate-no-end.docx",
                                                                    "move-pair-calibration.docx", "move-from-start-no-end.docx"}
# The driver opens files in name order (#671).
for label in CHUNKS:
    files = sorted(json.loads(l)["file"] for l in (ROOT / label / "specimens.jsonl").read_text().splitlines())
    for run in (ROOT / label, ROOT / label / "pass2"):
        assert [json.loads(l)["original_filename"] for l in (run / "pdf/manifest.jsonl").read_text().splitlines()] == files, run
day = f"{min(starts):%Y-%m-%d}"
assert day == f"{max(ends):%Y-%m-%d}"
n = len(rows)
I = "https://github.com/jandira-tech/docx-validate/issues/"
out = [
    f"### Session 91: {min(starts):%H:%M}Z–{max(ends):%H:%M}Z on {day}, validator columns at {rev[:8]}",
    "",
    f"The three shapes the malformation audit found unjudged ([#1212]({I}1212)), which #1213's `word-field-unbalanced`, "
    "`word-move-range-unpaired` and `xml-package-markup-compatibility` report as word-valid warnings and strict errors. One "
    "chunk, on the minimal package with its one run replaced or one part added: a body field with only a `begin` "
    "`w:fldChar`, one with `begin`, a `PAGE` instruction and `separate` but no `end`, an orphan `end`, and a balanced `PAGE` "
    "field calibration; a move-from range named `a` with no move-to range, a move-from start with no end beside its move-to "
    "pair, and a paired move calibration; and a `customXml/item1.xml` the main document relates whose `mc:Choice` "
    "`Requires` an undeclared prefix, with a calibration declaring it.",
    "",
    "The chunk ends with a minimal control. It ran twice, as two separate driver runs of byte-identical copies, and each "
    "run's rows were read twice: from its own Word log (session 41's `logcheck.py`) and by `wordpdf_outcomes.py`. Outcome "
    f"is the manifest spelling when both runs and both readings agree, and `unknown` otherwise; "
    f"{sum(r['agreed'] for r in results.values())} of {n} rows agree. The builder judged every row at `{rev}`, the #1213 "
    "head. Both runs waited until no other session's Word driver had run for 90 s.",
    "",
    "- **Word opens every shape clean.** No dialog named any row, in either run.",
    "- **It renders the broken fields as plain text.** The calibration's `PAGE` field computed `1`; the field with no `end` "
    "rendered its instruction, `PAGE`, before the text, and the `begin`-only and orphan-`end` rows rendered the text alone.",
    "- **It renders both sides of a move,** paired or not: the calibration and the start with no end show `HelloHello`, "
    "and the unpaired move-from shows its text.",
    "",
    f"Word-valid at {rev[:8]} matches Word on {sum(r['matches'] for r in results.values())} of {n} rows: it passes every "
    "row and warns on the six defective ones. Strict refuses those six, as its profile intends.",
    "",
    f"| Run | Observed | Specimen | Shape | SHA-256 (first 16) | Word, run 1 | Word, run 2 | Outcome | Word rendered | word-valid at {rev[:8]} | strict at {rev[:8]} |",
    "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    *rows,
    "",
    "<details><summary>Raw records, session 91</summary>",
    "",
    "```jsonl",
    *raw,
    "```",
    "",
    "</details>",
    "",
    "<details><summary>Session 91 builder, cross-check and section scripts</summary>",
    "",
    "Reading the logs used session 41's `logcheck.py`, above, unchanged. The builder ran from the root of a clean "
    "checkout of the committed tree; its refusal of a tree with uncommitted changes (CodeRabbit on #1182) was added after "
    "the build, and is the only change since.",
    "",
]
for name, path, lang in (("s91builder.mts", ROOT / "s91builder.mts", "ts"), ("compare.py", ROOT / "s91/compare.py", "python"),
                         ("section.py", ROOT / "s91/section.py", "python")):
    out += [f"`{name}`:", "", f"````{lang}", path.read_text().rstrip("\n"), "````", ""]
out += ["</details>", ""]
(ROOT / "s91/section.md").write_text("\n".join(out))
print(n, "rows,", len(raw), "raw records")
`````

</details>
