Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .githooks/validate-bot-directives.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ validate_file() {
fi
}

# If staged files provided, only check those
# If staged files provided, only check those that sit under .machine_readable/,
# the same population scan mode checks below. Without this fence the grep ran
# over every staged prose file, so any README naming the AI tool "Codex"
# could not be committed (owner ruling D316).
if [ -n "$STAGED_FILES" ]; then
while IFS=$'\n' read -r file; do
[ -z "$file" ] && continue
case "$file" in
.machine_readable/*|*/.machine_readable/*) ;;
*) continue ;;
esac
# Check all text files
case "$file" in
*.md|*.txt|*.adoc|*.yml|*.yaml|*.json|*.toml|*.sh|*.bash|*.js|*.ts|*.rs|*.ex|*.exs) ;;
*.a2ml|*.deed|*.md|*.txt|*.adoc|*.yml|*.yaml|*.json|*.toml|*.sh|*.bash|*.js|*.ts|*.rs|*.ex|*.exs) ;;
*) continue ;;
esac
[ -f "$file" ] || continue
Expand Down
40 changes: 40 additions & 0 deletions scripts/tests/validate-bot-directives-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
#
# Tests for .githooks/validate-bot-directives.sh in staged mode.
#
# Staged mode used to grep EVERY staged prose file for codex|gci|other-bot,
# while scan mode only looks under .machine_readable/. A README that names the
# AI tool "Codex" therefore could not be committed (owner ruling D316). These
# cases pin both halves: prose outside .machine_readable/ is not the gate's
# business, and a directive file inside it still fails (the planted positive
# control; without it a validator that checks nothing would pass every case).
set -uo pipefail
HOOK="$(cd "$(dirname "$0")/../.." && pwd)/.githooks/validate-bot-directives.sh"
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
pass=0; fail=0

# ck NAME EXPECTED_EXIT STAGED_PATH... β€” run the hook from $T in staged mode
# over the given relative paths and compare its exit code with EXPECTED_EXIT.
ck() {

Check warning on line 20 in scripts/tests/validate-bot-directives-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaES9Zqaetsf1Ft1bMzk&open=AaES9Zqaetsf1Ft1bMzk&pullRequest=1179
local name="$1" want="$2" out rc; shift 2
out="$(cd "$T" && INPUT_STAGED_FILES="$(printf '%s\n' "$@")" bash "$HOOK" 2>&1)"; rc=$?
if [ "$rc" = "$want" ]; then printf ' ok %s (exit %s)\n' "$name" "$rc"; pass=$((pass+1))

Check failure on line 23 in scripts/tests/validate-bot-directives-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaES9Zqaetsf1Ft1bMzj&open=AaES9Zqaetsf1Ft1bMzj&pullRequest=1179
else printf ' FAIL %s (expected exit %s, got %s) output=%s\n' "$name" "$want" "$rc" "${out:-<none>}"; fail=$((fail+1)); fi
}

mkdir -p "$T/docs" "$T/.machine_readable/bot_directives" "$T/sub/.machine_readable"
printf 'Agents: Claude, Gemini, Codex.\n' > "$T/docs/README.adoc"
printf '(bot codex)\n' > "$T/.machine_readable/bot_directives/legacy.deed"
printf 'gci = true\n' > "$T/sub/.machine_readable/x.a2ml"
printf '(bot claude)\n' > "$T/.machine_readable/bot_directives/ok.deed"

ck "prose naming Codex outside .machine_readable passes" 0 docs/README.adoc
ck "deprecated directive in .machine_readable .deed fails" 1 .machine_readable/bot_directives/legacy.deed
ck "nested .machine_readable .a2ml directive fails" 1 sub/.machine_readable/x.a2ml
ck "clean directive file passes" 0 .machine_readable/bot_directives/ok.deed
ck "mixed set fails on the directive file alone" 1 docs/README.adoc .machine_readable/bot_directives/legacy.deed

printf '%s passed, %s failed\n' "$pass" "$fail"
[ "$fail" -eq 0 ] && [ "$pass" -gt 0 ]

Check failure on line 40 in scripts/tests/validate-bot-directives-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaES9Zqaetsf1Ft1bMzl&open=AaES9Zqaetsf1Ft1bMzl&pullRequest=1179

Check failure on line 40 in scripts/tests/validate-bot-directives-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaES9Zqaetsf1Ft1bMzm&open=AaES9Zqaetsf1Ft1bMzm&pullRequest=1179
Loading