From b0e25b50598c06017ad6bce63df4d184b8287894 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:51:33 +0000 Subject: [PATCH] fix(rsr): make the estate census trustworthy Two defects found by running the freshly-merged census against the live estate. Both made the detector confidently wrong, which is worse than silent: * Blob-only listing. `.machine_readable/bot_directives` is a *directory*, so a blob-only census could never match it and the check was reported DEAD (0/262) when the true figure is 137/262. Trees are now emitted alongside blobs. * Stale tip. The census resolved the branch through /commits/HEAD, which is cacheable and observably lags. Immediately after squash-merging JuliaForChildren.jl, /commits/HEAD still reported the pre-merge commit (bfcd9683) while /git/refs/heads/main, /branches/main and git ls-remote all agreed on the real tip (1511c8a0). The census therefore described a repository that no longer existed in that state. The tip is now resolved through /git/refs/heads/, which is authoritative. Verified after the fix: census for JuliaForChildren.jl shows root .well-known/ absent and www/.well-known/ present, matching main. Detector over 262 repositories reports www/.well-known/security.txt at 248/262 and no false DEAD. --- scripts/rsr-census.sh | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/scripts/rsr-census.sh b/scripts/rsr-census.sh index 8ba20f5e..28c45aa8 100755 --- a/scripts/rsr-census.sh +++ b/scripts/rsr-census.sh @@ -23,6 +23,7 @@ TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}" OUT="${RSR_CENSUS_DIR:-.rsr-census}" REPOS_FILE="" ORG="${ORG:-hyperpolymath}" +BRANCH="${BRANCH:-main}" REFRESH=0 while [ $# -gt 0 ]; do @@ -40,15 +41,40 @@ done mkdir -p "$OUT" fetch_tree() { - # One recursive tree call per repo. Returns newline-separated blob paths. - local repo="$1" + # Two calls per repo: resolve the branch tip to a commit SHA, then fetch + # that exact tree. + # + # Both details matter: + # * Pinning to a SHA rather than asking for `HEAD` makes the census + # reproducible and stops the trees API serving a cached pre-merge tree. + # Observed: immediately after a squash-merge, `trees/HEAD` still + # returned the old tree for that repository. + # * Trees are emitted as well as blobs. Some rule-table checks name a + # *directory* (.machine_readable/bot_directives), which can never match + # a blob-only listing and would be reported as a false DEAD. + # Resolve the branch tip through the ref API, NOT /commits/HEAD. + # /commits/HEAD is cacheable and observably lags: immediately after a + # squash-merge it still reported the pre-merge commit for that repository + # (bfcd9683) while /git/refs/heads/main, /branches/main and git ls-remote + # all agreed on the real tip (1511c8a0). Pinning to a stale SHA would make + # the census confidently wrong, which is worse than unpinned. + local repo="$1" sha + sha=$(curl -sS \ + -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/$ORG/$repo/git/refs/heads/$BRANCH" \ + | jq -r '.object.sha // empty') + if [ -z "$sha" ]; then + printf '__ERROR__ could not resolve refs/heads/%s\n' "$BRANCH" + return + fi curl -sS \ -H "Authorization: Bearer $TOKEN" \ -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$ORG/$repo/git/trees/HEAD?recursive=1" \ + "https://api.github.com/repos/$ORG/$repo/git/trees/$sha?recursive=1" \ | jq -r ' if .tree then - .tree[] | select(.type == "blob") | .path + .tree[] | select(.type == "blob" or .type == "tree") | .path else "__ERROR__ \(.message // "unknown")" end'