diff --git a/scripts/check-phase3.sh b/scripts/check-phase3.sh new file mode 100755 index 0000000..0393e7a --- /dev/null +++ b/scripts/check-phase3.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# Repeatable Phase 3 verification: root and app vet/test/race, focused real +# genres parity, corpus audit, and the Phase 2 harness regression. +# Docker is required; unavailable Docker is a failed gate, never a skip. +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +APP="$(cd "$ROOT/../fonoteka.go" && pwd)" +PHP_ROOT="${PHP_ROOT:-/media/nvme/dev/golem15/fonoteka}" +ROUTES_PHP="$PHP_ROOT/plugins/golem15/fonoteka/routes.php" + +if ! command -v docker >/dev/null 2>&1; then + echo "refuse: docker is required for Phase 3 Postgres and PHP regression" >&2 + exit 1 +fi +if ! docker info >/dev/null 2>&1; then + echo "refuse: docker daemon is not available" >&2 + exit 1 +fi + +run_module() { + local name="$1" + local dir="$2" + echo "==> ${name} (${dir})" + ( + cd "$dir" + go vet ./... + go test ./... + go test -race ./... + ) +} + +echo "==> docker is available" +run_module "root" "$ROOT" +run_module "app" "$APP" + +echo "==> focused genres parity (one real ported pass)" +( + cd "$APP" + go test ./parity -count=1 -run 'TestParityCorpus$' +) + +echo "==> focused genre security and tenant isolation" +( + cd "$APP" + go test ./parity -count=1 -run 'TestGenreSecurityBoundaries|TestGenreCountsScopedToActiveCollection|TestGenreQueryFailsOnWrongLocale' +) + +echo "==> corpus audit" +CORPUS_ARGS=( + --manifest "$APP/parity/manifest.yaml" + --require-recorded + --require-clients + --check-secrets +) +if [[ -f "$ROUTES_PHP" ]]; then + CORPUS_ARGS+=(--routes "$ROUTES_PHP") +fi +( + cd "$APP" + go run ./parity/check_corpus.go "${CORPUS_ARGS[@]}" +) + +echo "==> Phase 2 harness regression" +bash "$ROOT/scripts/check-phase2.sh" --fresh-php + +echo "phase3 check passed"