#!/usr/bin/env bash # ci/tests/touched-requirements.test.sh — regression tests for the content scan in # ci/touched-requirements.sh, focused on rule 3: R-IDs cited only in a whole-line # YAML/shell `#` comment are PROSE (a reference), not a declaration, and must NOT be # attributed — while R-IDs on real code/spec lines still ARE. # # The tests point the real script at a THROWAWAY git repo via the REPO_ROOT override # (ci/lib.sh honours a pre-set REPO_ROOT); the script itself is run from its true # location so it still sources the real lib.sh. No network, no cluster. # # Run: ci/tests/touched-requirements.test.sh (or `make -C ci test`) set -euo pipefail CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" SCRIPT="${CI_DIR}/touched-requirements.sh" PASS=0 FAIL=0 ok() { printf ' ok %s\n' "$*"; PASS=$((PASS+1)); } bad() { printf ' FAIL %s\n' "$*"; FAIL=$((FAIL+1)); } # assert_absent assert_absent() { if grep -qxF "$1" <<<"$2"; then bad "$3 (found unexpected '$1' in: $(tr '\n' ' ' <<<"$2"))"; else ok "$3"; fi } # assert_present assert_present() { if grep -qxF "$1" <<<"$2"; then ok "$3"; else bad "$3 (missing '$1' from: $(tr '\n' ' ' <<<"$2"))"; fi } TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT git -C "$TMP" init -q -b main git -C "$TMP" config user.email t@t.t git -C "$TMP" config user.name t git -C "$TMP" config commit.gpgsign false # throwaway repo: never sign (ignore host gpg config) mkdir -p "$TMP/notes" # a path OUTSIDE path_requirements() so we isolate the content scan echo "baseline" > "$TMP/notes/base.txt" git -C "$TMP" add -A && git -C "$TMP" commit -qm baseline git -C "$TMP" checkout -q -b feature # A YAML file: an R-ID in a whole-line comment (must be IGNORED) and an R-ID on a real # value line (must be DETECTED). Also an indented comment, to prove leading space is fine. cat > "$TMP/notes/example.yaml" <<'YAML' # This header explains R-DOC-01 and must NOT be attributed. kind: Thing metadata: name: implements-R-REAL-01 spec: note: value # trailing inline comment mentioning R-INLINE-01 (conservatively still seen) # deeply indented comment about R-DOC-02 — also NOT attributed YAML # A shell file: a `#` comment R-ID (IGNORED) plus a real command line R-ID (DETECTED). cat > "$TMP/notes/example.sh" <<'SH' #!/usr/bin/env bash # doc: this script relates to R-SHDOC-01 (comment only — ignored) echo "runs check for R-SHREAL-01" SH git -C "$TMP" add -A && git -C "$TMP" commit -qm feature OUT="$(REPO_ROOT="$TMP" BASE_REF=main "$SCRIPT" 2>/dev/null)" printf 'touched set:\n%s\n---\n' "$OUT" # Comment-only citations are dropped (rule 3): assert_absent "R-DOC-01" "$OUT" "whole-line YAML comment R-ID is NOT attributed" assert_absent "R-DOC-02" "$OUT" "indented YAML comment R-ID is NOT attributed" assert_absent "R-SHDOC-01" "$OUT" "shell '#' comment R-ID is NOT attributed" # Real code/spec lines still count: assert_present "R-REAL-01" "$OUT" "R-ID on a real YAML value line IS attributed" assert_present "R-SHREAL-01" "$OUT" "R-ID on a real shell command line IS attributed" # Conservative: a trailing inline comment on a REAL line is still seen (only whole-line # comments are dropped) — documents the intentional boundary of the fix. assert_present "R-INLINE-01" "$OUT" "inline comment on a real line is (conservatively) still seen" # Removed comment lines are also excluded, while removed real lines still count. The file # must EXIST at the base, so we diff the removal against the commit that added it. git -C "$TMP" checkout -q -b feature2 main cat > "$TMP/notes/todelete.yaml" <<'YAML' # will delete a comment citing R-DELDOC-01 and a real line citing R-DELREAL-01 kind: Thing name: implements-R-DELREAL-01 YAML git -C "$TMP" add -A && git -C "$TMP" commit -qm add ADD_SHA="$(git -C "$TMP" rev-parse HEAD)" git -C "$TMP" rm -q "$TMP/notes/todelete.yaml" && git -C "$TMP" commit -qm remove OUT2="$(REPO_ROOT="$TMP" BASE_REF="$ADD_SHA" "$SCRIPT" 2>/dev/null)" printf 'touched set (removal):\n%s\n---\n' "$OUT2" assert_absent "R-DELDOC-01" "$OUT2" "REMOVED whole-line comment R-ID is NOT attributed" assert_present "R-DELREAL-01" "$OUT2" "REMOVED real-line R-ID IS attributed" # --------------------------------------------------------------------------------------- # PATH MAP — bootstrap/* (added 2026-09-13) # # WHY THIS IS LOCKED DOWN. path_requirements() keys `bootstrap/*` to R-STATE-03 + # R-GITOPS-01, and until 2026-09-13 the comment justifying it described # `bootstrap/standup.sh` as a file that carries the placeholder guards. That file has never # been on `main` (it landed only on unmerged prod-standup branches), so the comment was # stale and the entry looked like dead weight someone would tidy away. It is not dead: it # is what SELECTS conformance/tests/l0-static/placeholder-guard-coupling for the change # that eventually lands a placeholder guard under bootstrap/ — and that test discovers its # guard by content rather than by path, so it activates on exactly that change. Removing # the entry would let the change introducing a guard be gated by nothing, which is the # 2026-09-05 class. These assertions make the entry's deletion a test failure rather than a # silent loss of selection. # # NOTE the R-ID content scan must not be what produces these: `notes/` is outside the path # map precisely so the other cases isolate the scan, and here the file content cites no # R-ID at all, so any R-ID in the output came from the PATH. git -C "$TMP" checkout -q -b feature3 main mkdir -p "$TMP/bootstrap/flux" cat > "$TMP/bootstrap/flux/bootstrap.sh" <<'SH' #!/usr/bin/env bash # a bootstrap-path change that cites no requirement id of its own echo "flux bootstrap" SH git -C "$TMP" add -A && git -C "$TMP" commit -qm "touch bootstrap/" OUT3="$(REPO_ROOT="$TMP" BASE_REF=main "$SCRIPT" 2>/dev/null)" printf 'touched set (bootstrap/ path map):\n%s\n---\n' "$OUT3" assert_present "R-STATE-03" "$OUT3" "bootstrap/* attributes R-STATE-03 (selects placeholder-guard-coupling)" assert_present "R-GITOPS-01" "$OUT3" "bootstrap/* attributes R-GITOPS-01 (it IS the GitOps bootstrap path)" # And the neighbouring entry the same test leans on for its other half: clusters/* must # attribute R-ENV-02, which is what selects placeholder-guard-coupling's HALF A (the # authored-values sweep over clusters/ effective cluster-vars). git -C "$TMP" checkout -q -b feature4 main mkdir -p "$TMP/clusters/base" printf 'kind: ConfigMap\nmetadata:\n name: cluster-vars\n' > "$TMP/clusters/base/cluster-vars.yaml" git -C "$TMP" add -A && git -C "$TMP" commit -qm "touch clusters/" OUT4="$(REPO_ROOT="$TMP" BASE_REF=main "$SCRIPT" 2>/dev/null)" printf 'touched set (clusters/ path map):\n%s\n---\n' "$OUT4" assert_present "R-ENV-02" "$OUT4" "clusters/* attributes R-ENV-02 (selects placeholder-guard-coupling HALF A)" assert_present "R-GITOPS-01" "$OUT4" "clusters/* attributes R-GITOPS-01" echo if [ "$FAIL" -eq 0 ]; then echo "touched-requirements tests: PASS ($PASS assertions)"; exit 0; else echo "touched-requirements tests: FAIL ($FAIL failed, $PASS passed)"; exit 1; fi