A completed collection and a valid ZIP can sound like proof that every expected item is present. Reviewing an older shared-crawler job, I compared its ledger with the files before repeating the completion figures. Several saved rows referred to the same path, and one current ledger reference did not match the folder or archive despite the archive passing its corruption check. Those results needed separate names.
Start by identifying what each count measures
The record total counts rows describing requests and processing outcomes. Successful save rows are the subset that report a stored path without an error. A unique-file count must instead count each path once. Archive members can also include reports and documentation beyond those referenced files. Adjacent numbers on a dashboard do not necessarily have the same unit.
The original _record function appends an outcome and increments save or failure counters separately. Its save counter is not automatically the number of distinct file paths. For this review I read the actual ledger and rebuilt a set of paths from its successful rows. The public example uses synthetic values rather than customer site names, URLs or captured material.
The resume path can read an existing HTML file and reuse its bytes. A successful-save count therefore cannot simply be called the number of files newly fetched over the network during this run. Reporting reused material separately from fresh responses would require an explicit provenance record. I did not add that meaning to a counter whose contract does not supply it.
Repeated paths do not all have the same explanation
The selected ledger contains repeated rows with the same final URL and path. It also contains cases where different URLs point to one stored path. Processing history and a single current file are therefore different objects. I did not treat every repeated row as disposable duplication.
The crawler records the final response address and derives a storage name from a URL. It includes a query fingerprint, a hashed destination for long paths and a fallback for file-versus-directory conflicts. Even so, one final path does not prove that the bytes from every request referring to it were preserved separately. The reviewed ledger lacks a per-request original-byte digest, so that stronger claim could not be established.
Equal counts can conceal different members
Suppose a synthetic ledger has four successful rows, two of which refer to a.bin. Its distinct expected paths are a.bin, b.bin and c.bin. The ZIP contains a.bin, b.bin and one readme. Both the expected-path count and archive-file count are three, but c.bin is absent. The counts agree while the reference sets disagree.
I therefore inspect row count, unique-path count, archive-file count and the actual missing-reference set separately. Extra documentation is not inherently an error, but it cannot stand in for an absent resource. The static table below illustrates that relationship without exposing any actual collection target's filenames or contents.
Archive integrity and ledger coverage answer different questions
I listed the existing ZIP and ran its CRC and header check without finding a bad member. That check concerns members inside the archive. Coverage of an external ledger requires a separate comparison between its expected paths and the archive's member names.
That comparison found one path reported by current successful-save records that was absent from the ZIP. It was not a file at that path in the current collection folder either, and no archive name matched through casing or Unicode normalization. This establishes a current reference mismatch. It does not establish when or why it arose, whether it existed at creation time, or whether equivalent bytes survive at another location.
Do not silently repair a missing reference with a similar file
A matching basename in another folder is not sufficient reason to redirect a ledger reference. That can change the source relationship. Similar names existed in this case, but there was no expected byte digest establishing an interchangeable replacement. I retained the mismatch and the ledger and ZIP fingerprints in a private evidence record and left the original collection unchanged.
Any later recovery should begin with the relationship among the original request, final response and stored path. An alternative file remains a candidate until there is evidence that its contents match. Changing a path or deleting an error merely to display completion would make the recovery harder to explain. This content task did not expand into repairing the original collection or recrawling an external site.
Keep request failures separate from packaging failures
The original HTTP collection loop records failures and continues processing other material. Its job can reach completed when the loop ends while retaining a separate failure count. The browser-supplement importer instead reports partial and a failing exit code when that supplement has failures. One completion word should not erase the different contracts of those stages.
Archive creation writes a temporary file before replacing the export and collects individual unreadable-file errors. A failed server request and a local packaging failure are different events. An empty packaging-error list does not establish that every reference exists or that every web resource was discovered. The report's creation time and the scope of the archive examined now also belong in the evidence record.
Reuse the existing byte-comparison component
The shared compare_download_bytes implementation computes the length and SHA-256 of supplied bytes and compares declared completion, received length and an optional expected digest. When no expected digest is supplied, it distinguishes a newly computed fingerprint from a comparison with the original content. That distinction matters when a historical collection lacks original per-response fingerprints.
The package does not automatically audit crawler scope or an archive against its ledger. I checked the current public package's bytes and hash, extracted it and reran its existing thirty-six synthetic checks. Byte comparison is the reused responsibility; the reference-set comparison remains separately recorded in this run's private audit. Original captured customer-site material was not repackaged for sharing.
Hand over verified relationships rather than one completion total
A useful handoff distinguishes what was requested and failed, which paths the ledger claims to have stored, which members exist in the current ZIP and whether an expected digest was compared. The next person can then decide whether another collection, a ledger correction or additional evidence is appropriate. Verification of selected material is not proof of a complete site capture.
This routine ran no crawler and opened no browser. Its work was selected-source review, read-only comparison of historical metadata and the existing ZIP, and tests of a shared synthetic module. It changed neither the original collection scope nor its access boundary. I wanted to leave an account of which figures connect to which files, because rebuilding a website also depends on finding trustworthy material for the next revision.