open-standards/scripts/check-public-names.sh
Transaction Science 5fb5070f89 wai-quantum WebGPU member: CI review fixes
- The hardware job fetches the commit it must test by its full SHA, not the
  ref: a later commit on main that this workflow's paths do not match would
  otherwise be fetched instead, failing the job with nothing to retest it.
- The path filters add wai-rs's Cargo.toml, Cargo.lock and lib.rs and the
  toolchain pin: the GPU jobs build wai-rs with the forwarded feature, --locked,
  and no other workflow does.
- The public-names check reads .wgsl files: the crate ships its shader.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 23:29:10 -04:00

115 lines
4.3 KiB
Shell
Executable file

#!/usr/bin/env bash
#
# check-public-names.sh
#
# Holds WAI's public text to its naming rule: it names no company, vendor,
# customer or commercial product. Standards, standards bodies, protocols,
# papers and open-source projects may be named, factually.
#
# The patterns are NOT in this repository. They are read from the
# environment variable WAI_NAME_DENYLIST: newline-separated POSIX extended
# regular expressions, matched case-sensitively (write `[Ff]oo` where both
# cases matter). In CI the variable comes from a forge Actions secret of the
# same name; locally, export it from a private file before committing:
#
# WAI_NAME_DENYLIST="$(cat /path/to/private/patterns)" scripts/check-public-names.sh
#
# A public list would itself publish the names it exists to keep out.
#
# Scope: the tracked files under wai/ with the extensions .md .rs .toml .py
# .sh .mjs .js .json .html .css .ttl .h .c .txt, and wai/'s .gitignore files;
# or, when files are given as arguments, those files (the self-test,
# scripts/test-public-text-checks.sh, uses this). Excluded:
# - the settled OER/2 documents and corpus (wai/extensions/oer-receipts.md,
# wai/wai-rs/src/oer.rs, wai/oer-conformance/), which no change may edit.
#
# Opt-out, for a functional identifier only (a model-hub id a tool defaults
# to, a repository URL, an OS API name, a security advisory id, a capability
# string): put `allow-name: <reason>` on the same line, in a comment of the
# file's own syntax (`<!-- allow-name: reason -->`, `// allow-name: reason`,
# `# allow-name: reason`). The reason is required: it must contain a letter or
# a digit. Prose around such an identifier describes the standard or the
# function, not the owner.
#
# Exit status: 0 clean; 1 a hit; 2 WAI_NAME_DENYLIST unset or empty, a pattern
# grep cannot compile, or any other grep error. The check never reads an error
# as "clean".
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
if [ -z "${WAI_NAME_DENYLIST:-}" ]; then
echo "WAI_NAME_DENYLIST is not set: nothing to check against (see the header of $0)" >&2
exit 2
fi
patterns="$(mktemp)"
out="$(mktemp)"
trap 'rm -f "$patterns" "$out"' EXIT
printf '%s\n' "$WAI_NAME_DENYLIST" | grep -v '^[[:space:]]*$' > "$patterns" || true
if [ ! -s "$patterns" ]; then
echo "WAI_NAME_DENYLIST holds no pattern" >&2
exit 2
fi
# Compile every pattern once before scanning. grep exits 1 when nothing matches
# and 2 on an error; only 0 and 1 mean the patterns are usable. grep's message
# is suppressed: it could quote a private pattern.
set +e
grep -E -f "$patterns" /dev/null >/dev/null 2>&1
rc=$?
set -e
if [ $rc -gt 1 ]; then
echo "::error::WAI_NAME_DENYLIST holds a pattern grep cannot compile (grep exit $rc); nothing was checked" >&2
exit 2
fi
files=()
if [ $# -gt 0 ]; then
files=("$@")
else
while IFS= read -r f; do
case "$f" in
wai/extensions/oer-receipts.md|wai/wai-rs/src/oer.rs|wai/oer-conformance/*) continue ;;
esac
files+=("$f")
done < <(git ls-files 'wai/*.md' 'wai/*.rs' 'wai/*.toml' 'wai/*.py' 'wai/*.sh' 'wai/*.mjs' 'wai/*.js' \
'wai/*.json' 'wai/*.html' 'wai/*.css' 'wai/*.ttl' 'wai/*.h' 'wai/*.c' 'wai/*.txt' \
'wai/*.gitignore' 'wai/*.wgsl')
fi
if [ ${#files[@]} -eq 0 ]; then
echo "::error::no file to check" >&2
exit 2
fi
set +e
grep -HnE -f "$patterns" -- "${files[@]}" > "$out" 2>/dev/null
rc=$?
set -e
if [ $rc -gt 1 ]; then
echo "::error::grep failed (exit $rc) while scanning; nothing was checked" >&2
exit 2
fi
hits=0
while IFS= read -r line; do
content="${line#*:}"
content="${content#*:}"
if printf '%s' "$content" | grep -qE 'allow-name:[[:space:]]*[[:alnum:]]'; then
continue
fi
# Print the location only: the matched text may be a name the list keeps private.
if [ $hits -eq 0 ]; then
echo "::error::public text names a company, vendor, customer or product (patterns: WAI_NAME_DENYLIST)"
fi
echo "${line%%:*}:$(printf '%s' "${line#*:}" | cut -d: -f1)"
hits=$((hits + 1))
done < "$out"
if [ $hits -gt 0 ]; then
echo "Fix: name the standard, the standards body, the open-source project or the function instead;"
echo "for a functional identifier, mark the line with allow-name: <reason>."
exit 1
fi
echo "public-name check: clean (${#files[@]} files)"