From c6ae16d0199ae1c703c690292bed94d31d1398cb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 4 Jul 2026 20:49:59 -0700 Subject: [PATCH] fix(skills): scope card falsification match to the Expected section --- .../scripts/check-cards-against-spec | 17 ++++++++++++-- .../test-check-cards-against-spec.sh | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/skills/agentic-end-to-end-testing/scripts/check-cards-against-spec b/skills/agentic-end-to-end-testing/scripts/check-cards-against-spec index c0755655..81846092 100755 --- a/skills/agentic-end-to-end-testing/scripts/check-cards-against-spec +++ b/skills/agentic-end-to-end-testing/scripts/check-cards-against-spec @@ -34,6 +34,19 @@ warn() { echo "warn: $1"; } # design spec: markdown re-wrapping must not defeat the verbatim check.) normalize() { tr -s '[:space:]' ' ' | sed -e 's/^ //' -e 's/ $//'; } +# Text of the card's Expected section only (case-insensitive heading match, +# any ##+ level; section ends at the next heading or EOF). +expected_section() { + awk ' + /^#{2,}[[:space:]]/ { + low = tolower($0) + if (low ~ /^#+[[:space:]]*expected[[:space:]]*$/) { insec = 1; next } + if (insec) exit + } + insec { print } + ' "$1" +} + # --- extract the first table under the (case-insensitive) heading ---------- TABLE="$(awk ' /^#{1,6}[[:space:]]/ { @@ -104,10 +117,10 @@ while [ "$i" -lt "$ROWS" ]; do fail "missing card file: $f" i=$((i + 1)); continue fi - hay="$(normalize < "$f")" + hay="$(expected_section "$f" | normalize)" case "$hay" in *"$falsif"*) : ;; - *) fail "$f: falsification line not present verbatim. + *) fail "$f: falsification line not present verbatim in the ## Expected section. expected (normalized): $falsif" ;; esac grep -q '\*\*What this covers\*\*' "$f" || fail "$f: missing **What this covers**" diff --git a/tests/agentic-e2e-checker/test-check-cards-against-spec.sh b/tests/agentic-e2e-checker/test-check-cards-against-spec.sh index 5890c84c..516eb22f 100755 --- a/tests/agentic-e2e-checker/test-check-cards-against-spec.sh +++ b/tests/agentic-e2e-checker/test-check-cards-against-spec.sh @@ -119,6 +119,29 @@ assert_exit 1 "reworded falsification -> exit 1" \ "$CHECKER" "$TEST_ROOT/t3/spec.md" "$TEST_ROOT/t3/cards" assert_out_contains "widget-status-flags" "failure names the card" +echo "verbatim line outside Expected does not count" +make_spec "$TEST_ROOT/t3b"; make_cards "$TEST_ROOT/t3b/cards" +cat > "$TEST_ROOT/t3b/cards/widget-show-table.md" <<'EOF' +# widget-show-table: table renders with TOTAL + +**What this covers**: If stdout's last line is not `TOTAL` followed by the two-decimal sum (20.85 for the seed fixture), or the TOTAL row is absent entirely, the scenario FAILS. + +## Pre-state +A built widget binary. + +## Steps +1. Run `widget show`. + +## Expected +The widget prints a friendly banner and exits zero. + +## Cleanup +Nothing to clean. +EOF +assert_exit 1 "line only outside Expected -> exit 1" \ + "$CHECKER" "$TEST_ROOT/t3b/spec.md" "$TEST_ROOT/t3b/cards" +assert_out_contains "widget-show-table" "failure names the card" + echo "missing card file" make_spec "$TEST_ROOT/t4"; make_cards "$TEST_ROOT/t4/cards" rm "$TEST_ROOT/t4/cards/widget-show-table.md"