open-standards/scripts/check-no-vanity-metrics.sh
Transaction Science 60eab96364 ci: no-vanity-metrics scanner + pre-commit hook + CHARTER policy
Wires the no-vanity-metrics policy from prose-only into structural
enforcement. Without this, the next time a count creeps into a
README it stays there until I notice; with this, the PR fails.

What lands:

  - scripts/check-no-vanity-metrics.sh — bash scanner, dep-free,
    targets marketing/spec/governance Markdown only (per-phase
    progress docs, CHANGELOGs, conformance/notes/research dirs
    exempt by design). Regex is tuned to the patterns we've actually
    had to fix and rejects false positives on RFC / codec / version
    references. Lines that legitimately need a number opt out with
    `<!-- allow-vanity: <reason> -->`.
  - .github/workflows/no-vanity-metrics.yml — CI workflow runs the
    scanner on every PR and `main` push that touches Markdown.
  - .githooks/pre-commit — same scanner, local guard so the failure
    happens before push. Activated per-clone via
    `scripts/install-hooks.sh`.
  - CHARTER.md — adds a "Messaging — no vanity metrics" section
    documenting the policy and pointing to the scanner.

Also strips the four remaining drift sites the scanner found on
first run: a ~5 LOC stub note, a "98 crates" + "≤ 120 LOC" mention
in jouleclaw-stack/examples/AGENTS.md, and "26 crates" in the PCI
scope-map doc. The CAMT.054 ISO 20022 message-name reference is
preserved via an allow-vanity marker.
2026-06-02 10:39:43 -04:00

94 lines
3.4 KiB
Shell
Executable file

#!/usr/bin/env bash
#
# check-no-vanity-metrics.sh
#
# Blocks codebase-state numbers from landing in Markdown surfaces.
# Run by the no-vanity-metrics CI workflow and (optionally) by a
# local pre-commit hook (`scripts/install-hooks.sh`).
#
# Why: counts of crates / tests / LOC / adapters drift on every code
# change and create permanent sync debt between the website, the
# GitHub READMEs, and any memory document. The open-standards posture
# is "describe the shape, not the size."
#
# Opt-out: append `<!-- allow-vanity: <reason> -->` to the END of a
# line whose number is genuinely structural (a fact about an EXTERNAL
# spec, not a count of TX-side artefacts). The marker MUST give a
# reason. Misuse is caught by a separate audit.
#
# What gets flagged (the regex catches every count we've actually had
# to fix; tuned to avoid false positives on codec / RFC / spec
# references):
#
# - "N crates", "N+ crates"
# - "N tests passing", "N tests"
# - "N LOC", "~Nk LOC", "Nk LOC"
# - "N+ samplers"
# - "N+ adapters"
# - "N+ backends"
# - "N+ integrations"
#
# Identity-class numbers (spec versions like "JCR-1 v1", algorithm
# names like "Ed25519", RFC numbers, codec generation tags like
# "MPEG-4 Part 2") are NOT matched by the regex.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
# The vanity-metric pattern. Anchored to the keyword set with a
# trailing punctuation/space/EOL requirement so it doesn't fire on
# "Test-vector", "lockstep", "MPEG-4", RFC numbers, or version tags.
PATTERN='[0-9][0-9,]*[+kKMG]?[+ ]*([Cc]rates?|[Tt]ests?|LOC|loc|[Ss]amplers?|[Aa]dapters?|[Bb]ackends?|[Ii]ntegrations?)([ .,;:!?)$]|$)'
# Build the file list — marketing / spec / governance surfaces only.
# Historical progress notes (docs/*-progress.md), changelogs, and
# external corpora are EXEMPT by design (they're snapshots, not the
# message we're keeping in sync). Research and notes dirs also exempt.
# Portable: read into an array without `mapfile` so macOS bash 3.2 works.
files=()
while IFS= read -r f; do
case "$f" in
*-progress.md|*/docs/*-progress.md|*/CHANGELOG.md|*/conformance/*|*/research/*|*/notes/*|*/notes-*/*)
continue ;;
esac
files+=("$f")
done < <(git ls-files '*.md')
if [ ${#files[@]} -eq 0 ]; then
echo "no Markdown files to scan"
exit 0
fi
# Scan. A hit-line is exempted iff it ends with an `allow-vanity:`
# marker with a non-empty reason.
hits=0
while IFS= read -r line; do
# `line` is "path:lineno:content"
content="${line#*:}"
content="${content#*:}"
if echo "$content" | grep -qE 'allow-vanity:[[:space:]]*[^[:space:]]'; then
continue
fi
if [ $hits -eq 0 ]; then
echo "::error::Vanity metric(s) found — see scripts/check-no-vanity-metrics.sh for the policy and opt-out marker."
echo ""
fi
echo "$line"
hits=$((hits + 1))
done < <(grep -nE "$PATTERN" "${files[@]}" 2>/dev/null || true)
if [ $hits -gt 0 ]; then
echo ""
echo "Total hits: $hits"
echo ""
echo "Fix: replace the count with a shape description"
echo " (e.g. 'a multi-crate Rust workspace', 'covered by a test suite',"
echo " 'the diffusion sampler catalog'), OR if the number is genuinely"
echo " structural (describes an external spec, not TX state) append"
echo " '<!-- allow-vanity: <reason> -->' to the end of the line."
exit 1
fi
echo "✓ No vanity metrics found across $(echo "${files[@]}" | wc -w | tr -d ' ') Markdown files"