diff --git a/packages/mosaic/framework/tools/git/test-wrapper-guard.sh b/packages/mosaic/framework/tools/git/test-wrapper-guard.sh index bffa0d99..bd4035f4 100755 --- a/packages/mosaic/framework/tools/git/test-wrapper-guard.sh +++ b/packages/mosaic/framework/tools/git/test-wrapper-guard.sh @@ -515,6 +515,25 @@ FIXTURES="$TMP/fixtures.tsv" printf '0\t{"tool_input":{"command":"curl -s https://git.example.invalid/api/v1/repos/a/b/issues?q=a%%20b"}}\ta percent-escape in a READ is not this hook'"'"'s business\n' } > "$FIXTURES" +# Flake containment (#1380-FF, pipelines 2635/2637): a transient failure of the +# ASSERTION TOOLING (grep rc>=2 — fork/alloc error under node pressure) is not a +# contract drift, but the `if ! ... | grep -Fq` shape printed the identical +# FAIL line for both, failing merge verifies on correct guard output. Classify +# instead: retry tool errors 3x; rc=1 is the real mismatch; persistent tool +# failure reports TOOL-ERROR (fail stays 1 — never green on infra noise — but +# the line names the class so a re-run can be judged, not debugged). +assert_out_contains() { # needle why + local attempt rc1 + for attempt in 1 2 3; do + printf '%s' "$out" | grep -Fq -- "$1" && return 0 + rc1=$? + [ "$rc1" -eq 1 ] && return 1 # grep answered NO — real mismatch + sleep 0.2 # rc>=2: grep itself errored — retry + done + printf 'TOOL-ERROR %s (assertion grep failed 3x — infra/tooling, not guard drift)\n' "$2" >&2 + return 2 +} + fail=0 n=0 while IFS=$'\t' read -r want payload why remedy; do [ -n "${want:-}" ] || continue @@ -530,17 +549,6 @@ while IFS=$'\t' read -r want payload why remedy; do # if it never succeeds the case reports a TOOL-ERROR line (fail=1 stays, so # the run is never green-on-infra-noise, but the line names the real class # and a re-run can be judged instead of debugged as a guard defect). - assert_out_names() { - local attempt rc1 - for attempt in 1 2 3; do - printf '%s' "$out" | grep -Fq -- "$1" && return 0 - rc1=$? - [ "$rc1" -eq 1 ] && return 1 # grep answered NO — real mismatch - sleep 0.2 # rc>=2: grep itself errored — retry - done - printf 'TOOL-ERROR %s (assertion grep failed 3x; guard output was correct class — infra/tooling, not guard drift)\n' "$why" >&2 - return 2 - } if [ "$got" != "$want" ]; then printf 'FAIL %s (want exit %s, got %s)\n' "$why" "$want" "$got" fail=1 @@ -551,7 +559,7 @@ while IFS=$'\t' read -r want payload why remedy; do # so /issues/1/labels blocking with "use issue-create.sh" passed every run for # six rounds. Where a fixture states the remediation it expects, assert it. if [ -n "${remedy:-}" ]; then - assert_out_names "$remedy" + assert_out_contains "$remedy" "$why" arcret=$? if [ "$arcret" -eq 1 ]; then printf 'FAIL %s (blocked, but the advice does not name %s)\n' "$why" "$remedy" @@ -597,10 +605,15 @@ home_case() { fail=1 return fi - if [ -n "$needle" ] && ! printf '%s' "$out" | grep -Fq -- "$needle"; then - printf 'FAIL %s (exit %s, but the message does not say %s)\n' "$why" "$got" "$needle" - fail=1 - return + if [ -n "$needle" ]; then + assert_out_contains "$needle" "$why" + arcret=$? + if [ "$arcret" -eq 1 ]; then + printf 'FAIL %s (exit %s, but the message does not say %s)\n' "$why" "$got" "$needle" + fail=1 + return + fi + [ "$arcret" -eq 0 ] || { fail=1; return; } fi printf 'ok %s\n' "$why" } @@ -690,10 +703,15 @@ lone_case() { fail=1 return fi - if [ -n "$needle" ] && ! printf '%s' "$out" | grep -Fq -- "$needle"; then - printf 'FAIL %s [standalone] (exit %s, but the message does not say %s)\n' "$why" "$got" "$needle" - fail=1 - return + if [ -n "$needle" ]; then + assert_out_contains "$needle" "$why" + arcret=$? + if [ "$arcret" -eq 1 ]; then + printf 'FAIL %s [standalone] (exit %s, but the message does not say %s)\n' "$why" "$got" "$needle" + fail=1 + return + fi + [ "$arcret" -eq 0 ] || { fail=1; return; } fi printf 'ok %s [standalone]\n' "$why" }