Skip to content

Spec 001 T035: compare - #173

Merged
adamjohnwright merged 10 commits into
mainfrom
t035/compare-5
Nov 4, 2026
Merged

adamjohnwright merged 10 commits into
mainfrom
t035/compare-5

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Spec 001, task T035. Replaces #171 after its review (two mediums, fixed in the second-last commit); #171 replaced #168, #167 and #165.

Everything in #171 (pdf-export compare; nothing read from a PDF printed unless of a known shape; pdf.js quiet; UnreadPdf for PDF read failures), plus, from #171's review:

  • check-book's stop line said nothing useful (UnreadPdf, no file): it now names the file and pdf.js's error kind (<path> not read (InvalidPDFException)), keeping pdf.js's own error as an unprinted cause; file-system and graph errors print their own message, which holds no PDF text.
  • The contents reader's privacy test couldn't fail: it now reads a PDF whose pdf.js error does quote the planted word, and checks UnreadPdf's message doesn't.
  • A figure three pages into the last section tested; only console writing methods held; a doc comment restored; a gap recorded.

Tests: test/compare/ (59), test/check/unread.test.ts (4); 518 in all. Mutants in tasks.md.

🤖 Generated with Claude Code

adamjohnwright and others added 10 commits November 4, 2026 05:40
pdf-export compare <reference> <new> [--expected <file>], as contracts/cli.md
has it: each side a PDF or a folder, a folder compared file by file by name.
Both sides are read with pdf.js (lines, links, figures as clusters of images
and painted paths) and reduced to FR-012's parts: the cover's title, diagram,
excerpt note and distinct names (counted and hashed; U+2060 and no-break
spaces normalised); the introduction's release and counts; the analysis's
properties; each section's parts by their labels and their text; the
contents' entries and targets; each figure's kind. The literature and edit
history, which name people, are held as hashes. The JSON report gives each
difference by part, field and kind with a count and stable identifiers, list
order as a kind of its own; no section text and no name is printed.
--expected takes the recorded differences, with their reasons.

Tests print a sample document with pdf-export's layout and as a reference
in event-pdf's shape (placeholder names, wording written anew): each part's
difference is caught, and no name appears in any report. 21 mutants, each
caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t strict shapes

One printer (src/compare/output.ts) every reported value passes through:
text read from a PDF is printed only as a count, yes or no, a release, one
of a fixed list, a stable identifier, an analysis token of the service's
form or one of Reactome's species; anything else as a hash and a length,
salted once a run. Tested with names planted everywhere in 300 random
layouts a side.

- H1: the cover title is a hash, said only to be its file's name or not.
- H2: the analysis part ends at the first stable identifier or heading,
  and a property is kept only of its shape.
- M1: a contents target not read on either side is missing-target.
- M2: links, figures and targets read by page; 4,000 sections in 1.25 s
  (30.9 s before on the same layout); a file's bytes not copied twice.
- M3: the sections' order by their longest common subsequence, each
  occurrence of a repeated section compared with its own.
- Lows: --reference-margin; an unreadable file named and a difference;
  --expected refuses unknown keys, keeps an events record to differences
  with events, and lists records matching nothing; docs say what is done.

A second reference layout, unlike the sample's, found that a thin
connector must join a vector figure's shapes. 38 mutants, all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- M1: pdf.js's warnings quoted a PDF's content on standard error. Every
  getDocument reading a PDF that may hold names (compare, check-book, the
  contents' reader) now runs with verbosity ERRORS, and compare holds the
  console while it compares: a library's messages are counted and said
  once with their errors' kinds, never their words. Tested with a PDF
  whose content holds a planted word as an unknown operator.
- M2: a table's hairline borders joined its shaded header into a figure
  and its rows were lost. A line of thin paths now joins clusters only
  where it touches two or more node-sized ones, as a connector does.
- Lows: assertions that kill #167's surviving mutants; a missing path is
  exit 2 in the contract; the token is printed in its canonical form; the
  common subsequence's quadratic case recorded.

10 mutants, all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…by kind

- M1: a connector clipped at a reaction's small square was segments
  touching neither each other nor two nodes, so the diagram was no figure
  and its labels were read as text. Shapes under 4 pt are now pieces of
  lines like thin paths, so the segments and the square are one line,
  which joins the nodes at its ends; a shaded-header table still reads
  its rows.
- Found with it: the last section's figures were sought on its first
  page only, and the first section's heading could reach onto the cover.
- L1: pdf.js's errors quote the file. check-book's and the contents'
  readers turn them into UnreadPdf (src/print/unread.ts), said by kind
  alone, and check-book's stopped line prints kind and code only.
- L2/L3: every console method is held during a comparison, put back on
  failure too, the calls said in one line; each tested.
- L4/L5: the wording of what joins, and of tables still read as figures.

11 mutants, all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st can fail

- M1: check-book's stopped line printed the wrapper's kind alone, and fs
  and graph errors lost their path or message. UnreadPdf now names its
  file and pdf.js's error's kind (kept as `kind`, pdf.js's error as its
  `cause`, never printed); the stopped line prints the message, so fs and
  graph errors say theirs. Tested with a planted filter, a truncated PDF
  and a file it may not read.
- M2: the contents reader's test now reads a PDF whose destinations pdf.js
  throws on quoting the planted word, so a message carrying the cause's
  fails it.
- Lows: a figure three pages into the last section; only the console's
  writing methods held; landed's doc comment restored; a shaded header
  just below a figure among the known gaps.

7 mutants, all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit 28c347c into main Nov 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant