mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 15:21:30 +02:00
Screenshots carry a perceptual hash, so hosts whose pages look alike are grouped in the gallery and the table. An exact hash matches only identical bytes, which leaves the same login across forty tenants in forty groups of one, so this is a 64-bit dHash taken from a fixed viewport band. Clustering follows the view's scope rather than being frozen at finalize: one run on a scan page, every target on the project-wide view. A cluster is every row within SCREENSHOT_DISTANCE of one representative, so its count and the screenshot: filter it opens are the same set by construction. Thresholds are measured over 9,890 stored screenshots on four estates. Distance 2 collapses the cPanel port variants and a default page's one-bit variants while 4 begins merging different skins. A hash setting fewer than four bits is a blank render and never represents a cluster; a variance floor let a one-bit hash sink 79 hosts into one group. Screenshots are held as WebP at native size, 18% of PNG, converted by a background task rather than the stage: httpx writes the PNG itself, so converting inline saves no peak disk and costs every scan serial time. Only settled scans are touched, or the path is rewritten under a stage still writing it. The hash is taken before the encode and never recomputed, so compression leaves the grouping untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U2BnU1s9wZg3KYgCHBxhuC