Read absolute references, and close out what the orphans are - #46
Merged
Conversation
Two findings, from taking the orphan count apart rather than carrying it. The check could not read an absolute reference. Hugo writes one wherever a template resolves against the base, which the entry-cover image on every list page does, so those files were read as external. That cost both directions at once: 5 files were counted as orphans while being displayed on the site, and 18 references were never checked for existing at all. The second half is the serious one, since a missing file behind an absolute reference passed silently. The origin is read from the home page's canonical link rather than assumed, because staging and production build with different base URLs, and a missing canonical stops the run rather than being guessed at, since a wrong origin inflates the orphan count by exactly the pages that use one. ORPHANED_MEDIA falls 103 -> 98 as a consequence, and assets rises 1031 -> 1049. Neither number moved because the site changed. The remaining 98 are adjudicated rather than unknown, against the captured live site, whose crawl covers all 328 URLs the contract requires. 97 were uploaded to the old platform's media library and never placed on a published page. 1 is that platform's site icon, superseded by the favicon set at the static root. No conversion loss remains, and no image the old site served from its own uploads went unimported, so anything that raises the count from here is new. That is what the exact constant is for, and TODO.md loses the entry calling the cause unknown. Three traps in the adjudication are recorded in checks/README.md because each produced a wrong answer first. A regex cannot read nested elements and reported a fictional 194-figure loss where an HTML parser reports 19. Only a surplus in the mirror is a finding, since a shortfall means the parser missed that page's markup. The old platform generated an attachment page per upload and a foreign host may also serve /wp-content/uploads/, so counting attachment pages makes every unused upload look published and matching a path without its host attributes another site's file to this one. Both were hit here: 23 apparent losses collapsed to 1, and the one apparent never-imported file was a PDF on phyn.com. New coverage demonstrated failing before being trusted. Deleting a file that only an absolute reference names now fails the assets check, where it passed before. Removing the canonical link fails with the origin message. The three earlier orphan states are unchanged. Verified through make-release.sh and against the local mirror: PASS - 1245 URLs honored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the checks/check-url-parity.py URL/asset parity gate for the Hugo-built site by correctly treating same-site absolute asset references as local (instead of external), and by updating the orphan-media baseline and documentation to reflect the newly understood causes.
Changes:
- Derive the site’s origin from the built home page canonical link and use it to recognize same-origin absolute
/mediaand/externalreferences. - Update the recorded
ORPHANED_MEDIAbaseline (103 → 98) and refresh the in-script rationale accordingly. - Update documentation (
checks/README.md) and remove the now-obsolete TODO entry about unknown orphan causes.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
TODO.md |
Removes the TODO item claiming the orphaned media causes are unknown. |
checks/README.md |
Documents absolute-reference handling and summarizes the adjudicated orphan breakdown and known traps. |
checks/check-url-parity.py |
Adds site_origin() + absolute-ref extraction and updates ORPHANED_MEDIA baseline/comments. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Taking the orphan count apart rather than carrying it, per the two-class framing: referenced but absent is a serious miss, present but unreferenced is either a lost link or an upload that was never used. Both turned out to have an answer, and finding it exposed a defect in the check itself.
The check could not read an absolute reference
Hugo writes an absolute URL wherever a template resolves one against the base — the entry-cover image on every list page does exactly that:
collect_refsmatched only rooted paths, so those were read as external. That cost both directions at once:The second is the serious half — a missing file behind an absolute reference passed silently, which is precisely the "referenced but absent" class that must never be green.
The origin is now read from the home page's canonical link rather than assumed, because staging and production build with different base URLs and a hardcoded host would check one environment's output against another's. A missing canonical stops the run rather than being guessed at, since a wrong origin inflates the orphan count by exactly the pages that use one.
ORPHANED_MEDIAfalls103 -> 98andassetsrises1031 -> 1049as consequences. Neither number moved because the site changed.What the remaining 98 are
Adjudicated against the captured live site, whose crawl covers all 328 URLs the contract requires:
rel="icon"), superseded by the favicon set at the static rootZero conversion losses remain, and no image the old site served from its own uploads went unimported — the third class, the one neither check can see because both are relative to what was carried, is empty. So anything that raises the count from here is new, which is what makes the exact constant worth keeping.
Three traps, each of which produced a wrong answer first
Recorded in
checks/README.mdrather than only here, because each is cheap to re-trip:wp-block-galleryfigures containingwp-block-imagefigures; matching by pattern reported a fictional 194-figure loss where an HTML parser reports 19./wp-content/uploads/. Counting attachment pages as places an image was displayed makes every unused upload look published; matching an uploads path without checking its host attributes another site's file to this one. Both were hit: 23 apparent losses collapsed to 1, and the one apparent never-imported file was a PDF on phyn.com.Demonstrated failing before being trusted
FAIL assets, exit 1FAIL: cannot determine the site's own origin, exit 1Verification
Run through
make-release.shand against the local mirror:markdownlint, editorconfig-checker, and the module compile all clean.
TODO.mdloses the entry calling the orphan cause unknown, since it no longer is.🤖 Generated with Claude Code