Skip to content

v2026.9.13

Choose a tag to compare

@github-actions github-actions released this 13 Sep 01:09

What's changed since v2026.8.25

Sync no longer re-extracts files whose bytes did not change

An iCloud (or Dropbox) re-download rewrites an attachment's mtime without touching a byte. Triage treated every size/mtime mismatch as a changed source and re-extracted, even though each ready catalog entry already records a sha1 of the file.

  • A content hash now settles the question. When a ready entry's size still matches but its mtime moved, and the cached artifacts would otherwise be accepted, sync hashes the file and compares it to the recorded sourceHash. A match reuses the artifacts, writes the current mtime, and carries sourceHash / lastIndexedAt forward, so the next run is back to a plain stat comparison. A genuine in-place edit (re-OCR, replaced file) still hashes differently and re-extracts as before.
  • Hash-rescued entries stay out of the keyword update. Catalog comparison treats an equal non-empty sourceHash as proof of identical content, so an mtime-only change does not push a document back through the FTS update or defeat the no-change short-circuit.
  • Hashing never aborts a run. An unreadable file (permissions, I/O error, an evicted iCloud placeholder while offline) counts as "unknown" and takes the normal extract path, where a real failure is reported per file.
  • Recovery reuse records a hash when it can. An attachment reused from on-disk artifacts without a catalog entry now gets a sourceHash when the file's bytes are local. Dataless iCloud placeholders (stat works, reading triggers a download) are never read just for bookkeeping; they earn a hash when they are next extracted.
  • Failed re-extraction rolls back by the same rule. Where a sourceHash was recorded it is authoritative; the rollback writes the current stat with the previous hash so the kept artifacts are recognised next time.

An interrupted sync no longer truncates the catalog

Mid-flight progress writes used to persist only the entries triaged so far. Interrupting a run during extraction (SIGINT, crash) overwrote index/catalog.json with that partial list, permanently dropping the sourceHash / lastIndexedAt of every attachment still queued. Progress writes now carry the previous entries of queued attachments; entries that left the bibliography still disappear, and the final catalog is unchanged.