hyperhive/scripts/check-issue-refs.sh
atlas ab1b07acce ci(#1555): prose-ify legacy tracker tags; add lint:allow escape hatch
Clean the legacy backlog so the tracker-tag lint can become a required
gate (mara's warn-during-cleanup -> full-tree-enforcement path). Rewrite
the ~33 real `closes/see #NNN` provenance refs in doc-comments to prose
across hive-forge, hive-c0re, hive-ag3nt, hive-matrix-mcp, hive-sh4re,
and add a `lint:allow` line marker to check-issue-refs.sh for genuine
non-tracker `#<digits>` (a hash-digit heading-detection test input).
Tree is now lint-clean; tracker-tag lint ready to promote to required.
2026-06-10 13:14:42 +02:00

50 lines
2.4 KiB
Shell
Executable file

#!/bin/sh
# CI lint: flags tracker tags (a hash followed by an issue number) in
# source comments. The hive convention is prose, not tracker tags, in
# code (see /knowledge/hive-rules.md) — tags rot, they point at moving
# targets and leak tracker coupling into the source tree.
#
# Emits a CI error annotation per hit and exits 1 if any tag is found,
# 0 otherwise. It runs as its own CI job, deliberately kept OUT of the
# required checks while the legacy backlog is cleaned up: a hit turns
# the job red (a visible, non-blocking signal on the PR) without
# blocking merge. Promote it to a required check once the tree is clean
# to make it a hard gate — no code change, just branch-protection.
#
# Scope: tracked *.rs *.nix *.js *.ts *.css *.html. Markdown is exempt
# (prose docs may legitimately cite the tracker). The pattern matches a
# hash, 2-5 digits, then a non-alphanumeric char or end-of-line. A real
# tracker tag is never glued to a letter, so the trailing class skips
# both letter-bearing / 6-8-digit hex colours (the digit run breaks or
# overruns) and digit-runs followed by a letter — e.g. hash-route
# fragments like #24h. Residual: a pure-numeric short hex (e.g. three
# identical digits) trips it — write the six-digit form to dodge.
#
# Escape hatch: a line containing the marker `lint:allow` is exempt.
# Reserve it for genuine `#<digits>` that aren't tracker tags — e.g. a
# `#123` markdown-heading example or hash-prefixed test-input data —
# and keep a short reason next to the marker. Don't use it to keep a
# real tracker tag; rewrite those to prose.
set -eu
pattern='#[0-9]{2,5}([^0-9a-zA-Z]|$)'
# `/dev/null` forces grep to always print a filename prefix, even when
# xargs hands it a single file. `-r`/`-0` keep it robust to odd paths
# and an empty file list. Lines carrying the `lint:allow` marker are
# dropped (legitimate non-tracker `#<digits>`; see the header).
hits="$(
git ls-files -z '*.rs' '*.nix' '*.js' '*.ts' '*.css' '*.html' \
| xargs -0 -r grep -nE "$pattern" /dev/null 2>/dev/null \
| grep -v 'lint:allow' || true
)"
if [ -n "$hits" ]; then
echo "$hits" | while IFS=: read -r file lineno _; do
printf '::error file=%s,line=%s::tracker tag in source — write prose, not a hash-number tag (see /knowledge/hive-rules.md)\n' "$file" "$lineno"
done
count="$(printf '%s\n' "$hits" | wc -l | tr -d ' ')"
printf 'check-issue-refs: %s tracker tag(s) found in source\n' "$count" >&2
exit 1
fi
exit 0