ee6cb9e62a
lint-gate already existed to enforce "do not RELEASE a tree whose lint failed", because lint.yml does not run on tag pushes. scripts/check-doc-drift.sh had the same gap and it was never extended to cover it: check 9 ran only in lint.yml, so no tag build has ever evaluated it. Add it to lint-gate, which resolve-versions already needs, so it fails in ~8 s ahead of the 46-minute base build. For this check the gap is strictly worse than it is for shellcheck. Shellcheck judges the tree, so green on main is still green at the tag -- the bytes did not move. Check 9 judges the tree against upstream NOW, and the floating refs it watches move with no commit here at all, so a green reading on main carries no information about tag time. v1.9.3 is the worked example: pi-observational-memory moved cba0334 -> e7d77dc the day AFTER the tag, nothing went red, and it surfaced only because someone ran the gate by hand. Measured, not assumed: - Same file lint.yml calls (one reference in each workflow), not a second copy. - Works on a CI-shaped checkout: cloned --depth 1 --no-tags (0 tags, 1 commit), rc=0. It needs no local tags because `last` comes from the Hub tags API, not `git tag`, so the plain actions/checkout@v4 above is sufficient. - Has teeth: deleting the Unreleased section from that clone gives rc=1 and names the component; restoring it gives rc=0. - ~8 s (7.8-8.3 s measured), vs ~1 s for lint-shell.sh. Residual, accepted: the gate resolves the refs seconds before resolve-versions resolves them again, so an upstream push inside that window still slips past. Check 9 on the next release names it then.