mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
2abb5a0a1d
Closes the parity-drift loop that's caused 17/20 bats-tests + 13/20 cli-integration
failures on main. Two changes:
1. New scripts/check-test-fixture-parity.sh — pre-push validator that mirrors
the CI assertions which previously fired only on push:
* For each hooks/*.sh, basename must appear in tests/hooks/*.{sh,bats}
or tests/{skills,scripts}/test-<name>*.sh.
* For each helper-script reference in pre-push-gate.sh (matched by the same
regex as tests/scripts/pre-push-gate.bats:154), there must be a matching
make_stub line in pre-push-gate.bats setup().
Wired in as gate 5b under needs_check hook||shell. Bypass:
AGENTOPS_PARITY_GATE_DISABLED=1.
2. Embedded-hooks sync gate (pre-push-gate.sh:535) is now unconditional. Was
wrapped in `if needs_check hook` which silently skipped on diffs the
classifier didn't tag as hook-touching. ~0.5-1s overhead on pure-Go pushes;
targets the 7/20 embedded-sync recurrence.
Coverage: tests/scripts/test-check-test-fixture-parity.bats — 6/6 pass
(clean-fixture PASS, missing-coverage FAIL, missing-stub FAIL, 5da522e9-replay
FAIL, AGENTOPS_PARITY_GATE_DISABLED bypass, self-reference exclusion).
Plan: .agents/plans/2026-05-02-ci-parity-pre-push-gate.md
Research: .agents/research/2026-05-02-ci-failure-prevention.md
Pre-mortem: .agents/council/2026-05-02-pre-mortem-ci-parity-pre-push-gate.md
(WARN -> PASS after applying W1/W2/W3/W4 amendments inline.)
Epic: soc-zkhu (4/4 issues closed).
93 lines
3.6 KiB
Bash
Executable File
93 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# check-test-fixture-parity.sh — pre-push parity gate
|
|
#
|
|
# Mirrors the CI-side parity assertions that, when broken, surface only on
|
|
# push to main. Catches the pattern at developer time:
|
|
# 1. New hooks/<x>.sh added without a matching reference in any
|
|
# tests/{hooks,skills,scripts}/test-* file.
|
|
# 2. New scripts/<x>.sh referenced by scripts/pre-push-gate.sh but not
|
|
# stubbed in tests/scripts/pre-push-gate.bats setup().
|
|
#
|
|
# Output: silent PASS (exit 0). FAIL (exit 1) prints one line per category
|
|
# of missing entries followed by a suggested-fix line.
|
|
#
|
|
# Bypass: AGENTOPS_PARITY_GATE_DISABLED=1.
|
|
#
|
|
# Usage:
|
|
# scripts/check-test-fixture-parity.sh # use repo root from git
|
|
# scripts/check-test-fixture-parity.sh /path/to/root # use given root (for fixtures/tests)
|
|
|
|
set -euo pipefail
|
|
|
|
if [[ "${AGENTOPS_PARITY_GATE_DISABLED:-}" == "1" ]]; then
|
|
printf 'check-test-fixture-parity: skipped (AGENTOPS_PARITY_GATE_DISABLED=1)\n' >&2
|
|
exit 0
|
|
fi
|
|
|
|
ROOT="${1:-}"
|
|
if [[ -z "$ROOT" ]]; then
|
|
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
fi
|
|
|
|
HOOKS_DIR="$ROOT/hooks"
|
|
GATE_SCRIPT="$ROOT/scripts/pre-push-gate.sh"
|
|
BATS_FILE="$ROOT/tests/scripts/pre-push-gate.bats"
|
|
|
|
# --- Check 1: hook coverage parity ---
|
|
# For each hooks/*.sh (non-recursive — examples/ intentionally excluded), the
|
|
# basename must appear in at least one of the canonical test files.
|
|
missing_hooks=""
|
|
if [[ -d "$HOOKS_DIR" ]]; then
|
|
for hook_file in "$HOOKS_DIR"/*.sh; do
|
|
[[ -e "$hook_file" ]] || continue
|
|
hook_name="$(basename "$hook_file" .sh)"
|
|
coverage_files=()
|
|
# Mirror tests/hooks/test-hooks.bats:805-810: every .sh/.bats in
|
|
# tests/hooks/ counts as coverage. Plus per-hook test files in
|
|
# tests/{skills,scripts}/.
|
|
for candidate in \
|
|
"$ROOT/tests/hooks"/*.sh \
|
|
"$ROOT/tests/hooks"/*.bats \
|
|
"$ROOT/tests/skills/test-${hook_name}"*.sh \
|
|
"$ROOT/tests/scripts/test-${hook_name}"*.sh; do
|
|
[[ -e "$candidate" ]] && coverage_files+=("$candidate")
|
|
done
|
|
if [[ ${#coverage_files[@]} -eq 0 ]]; then
|
|
missing_hooks+=" $hook_name"
|
|
continue
|
|
fi
|
|
if ! grep -F -q "$hook_name" "${coverage_files[@]}" 2>/dev/null; then
|
|
missing_hooks+=" $hook_name"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# --- Check 2: pre-push helper-stub parity ---
|
|
# Extract every helper-script reference inside scripts/pre-push-gate.sh using
|
|
# the IDENTICAL regex as tests/scripts/pre-push-gate.bats:154 (W1 amendment).
|
|
# For each helper, assert tests/scripts/pre-push-gate.bats setup() contains
|
|
# a make_stub line for it.
|
|
missing_stubs=""
|
|
if [[ -r "$GATE_SCRIPT" && -r "$BATS_FILE" ]]; then
|
|
while IFS= read -r helper; do
|
|
# Skip self-reference
|
|
[[ "$helper" == "scripts/pre-push-gate.sh" ]] && continue
|
|
# Stub line in bats setup() looks like:
|
|
# make_stub "$FAKE_REPO/<helper>"
|
|
# or for the hash-snapshot helper, make_hash_snapshot_stub.
|
|
if ! grep -F -q "$helper" "$BATS_FILE" 2>/dev/null; then
|
|
missing_stubs+=" $helper"
|
|
fi
|
|
done < <(grep -oE '(scripts|tests|skills)/[A-Za-z0-9_./-]+[.]sh' "$GATE_SCRIPT" | sort -u)
|
|
fi
|
|
|
|
# --- Output ---
|
|
if [[ -z "$missing_hooks" && -z "$missing_stubs" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
[[ -n "$missing_hooks" ]] && printf 'hooks with no test coverage:%s\n' "$missing_hooks" >&2
|
|
[[ -n "$missing_stubs" ]] && printf 'pre-push helpers without bats stub:%s\n' "$missing_stubs" >&2
|
|
printf '\nAdd coverage in tests/hooks/test-hooks.{sh,bats} or tests/{skills,scripts}/test-<name>*.sh,\nand a make_stub line in tests/scripts/pre-push-gate.bats setup().\n' >&2
|
|
exit 1
|