The file tree diff reports a single "modified" bucket. After #13250 each manifest entry carries a hash of the text of the page and a hash of its markup, and comparing both tells two kinds of change apart:
text_hash differs — the copy changed, someone edited the page.
text_hash matches but markup_hash differs — only the markup moved: a link retargeted, an image swapped for another file, an :align: on a figure, a theme upgrade, an intersphinx tooltip carrying a new version of the project it points to.
Only the first kind is reported today. That's deliberate — a file list padded with pages nobody touched is a list people learn to ignore — but the second kind isn't nothing: a screenshot replaced under a new filename, or a link that now points somewhere else, are real changes a reviewer might want to see. Ranking them instead of dropping them gets both: pages whose copy changed first, pages whose markup moved collapsed underneath.
The work:
- A fourth
FileTreeDiffFileStatus member and the matching property on FileTreeDiff.
- A fourth key in
_get_filetreediff_response(). Additive rather than a per-file flag, so a client that doesn't know about it keeps rendering what it renders today instead of showing the markup-only pages unranked.
- The build overview comment, which is where the ranking pays off. The markup-only bucket is often large — an intersphinx version bump touches every page of a project — so it needs to be collapsed by default, or it recreates the noise problem one section down.
- The flyout in
readthedocs/addons.
This isn't blocked on anything: a file whose manifest entry predates #13250 has neither hash, so it can keep falling into the plain "modified" bucket the way it does now.
Once every manifest in storage has the new hashes, main_content_hash and the fallback that reads it in get_diff() can both go — there's a TODO on each.
🤖 Generated with Claude Code
The file tree diff reports a single "modified" bucket. After #13250 each manifest entry carries a hash of the text of the page and a hash of its markup, and comparing both tells two kinds of change apart:
text_hashdiffers — the copy changed, someone edited the page.text_hashmatches butmarkup_hashdiffers — only the markup moved: a link retargeted, an image swapped for another file, an:align:on a figure, a theme upgrade, an intersphinx tooltip carrying a new version of the project it points to.Only the first kind is reported today. That's deliberate — a file list padded with pages nobody touched is a list people learn to ignore — but the second kind isn't nothing: a screenshot replaced under a new filename, or a link that now points somewhere else, are real changes a reviewer might want to see. Ranking them instead of dropping them gets both: pages whose copy changed first, pages whose markup moved collapsed underneath.
The work:
FileTreeDiffFileStatusmember and the matching property onFileTreeDiff._get_filetreediff_response(). Additive rather than a per-file flag, so a client that doesn't know about it keeps rendering what it renders today instead of showing the markup-only pages unranked.readthedocs/addons.This isn't blocked on anything: a file whose manifest entry predates #13250 has neither hash, so it can keep falling into the plain "modified" bucket the way it does now.
Once every manifest in storage has the new hashes,
main_content_hashand the fallback that reads it inget_diff()can both go — there's aTODOon each.🤖 Generated with Claude Code