chore(agents): implement v2 hardening and enforcement-ready QA
This commit is contained in:
24
bin/dev
24
bin/dev
@@ -15,7 +15,9 @@ Commands:
|
||||
down Stop local containers
|
||||
logs [service] Follow docker compose logs (optional service)
|
||||
console <args...> Run php bin/console inside php container
|
||||
qa Run mandatory quality gates (QG-001/002/003/006)
|
||||
qa Alias for qa-required
|
||||
qa-required Run required quality gates (QG-001/002/003/006/008/009)
|
||||
qa-extended Run qa-required plus non-blocking checks (QG-004/005/007)
|
||||
USAGE
|
||||
}
|
||||
|
||||
@@ -95,12 +97,14 @@ cmd_logs() {
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_qa() {
|
||||
cmd_qa_required() {
|
||||
require_docker_compose
|
||||
docker compose exec -T php vendor/bin/phpunit
|
||||
docker compose exec -T php vendor/bin/phpstan analyse -c phpstan.neon --no-progress
|
||||
docker compose exec -T php vendor/bin/phpunit tests/Architecture/CoreStarterkitContractTest.php
|
||||
docker compose exec -T php vendor/bin/php-cs-fixer fix --config=tools/php-cs-fixer/.php-cs-fixer.dist.php --dry-run --diff --verbose
|
||||
"${repo_root}/bin/qa-required.sh"
|
||||
}
|
||||
|
||||
cmd_qa_extended() {
|
||||
require_docker_compose
|
||||
"${repo_root}/bin/qa-extended.sh"
|
||||
}
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
@@ -128,7 +132,13 @@ case "${command}" in
|
||||
run_console "$@"
|
||||
;;
|
||||
qa)
|
||||
cmd_qa "$@"
|
||||
cmd_qa_required "$@"
|
||||
;;
|
||||
qa-required)
|
||||
cmd_qa_required "$@"
|
||||
;;
|
||||
qa-extended)
|
||||
cmd_qa_extended "$@"
|
||||
;;
|
||||
-h|--help|help)
|
||||
usage
|
||||
|
||||
45
bin/qa-extended.sh
Executable file
45
bin/qa-extended.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd -- "${script_dir}/.." && pwd)"
|
||||
cd "${repo_root}"
|
||||
|
||||
warn() {
|
||||
echo "[WARN] $*"
|
||||
}
|
||||
|
||||
# Blocking baseline
|
||||
bin/qa-required.sh
|
||||
|
||||
# QG-004 (non-blocking in phase 1): structural checks as warning-only signal
|
||||
if command -v rg >/dev/null 2>&1; then
|
||||
c1="$( (rg 'new\\s+[^\\s(]+Factory\\(' lib/Service || true) | wc -l | tr -d '[:space:]')"
|
||||
c2="$( (rg --glob '!**/*Factory.php' 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' lib/Service || true) | wc -l | tr -d '[:space:]')"
|
||||
c3="$( (rg "\\b(accessServicesFactory|directoryServicesFactory|userServicesFactory|authServicesFactory|tenantServicesFactory|settingServicesFactory|userRepositoryFactory|authRepositoryFactory|authGatewayFactory)\\(" pages lib templates web || true) | wc -l | tr -d '[:space:]')"
|
||||
c4="$( (rg -n 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' pages -g '*.php' || true) | wc -l | tr -d '[:space:]')"
|
||||
c5="$( (rg -n '\\bDB::' pages -g '*.php' || true) | wc -l | tr -d '[:space:]')"
|
||||
c6="$( (rg -n 'app\\([^\\n]*Factory::class\\)->create' pages/admin -g '*.php' || true) | wc -l | tr -d '[:space:]')"
|
||||
c7="$( (rg -n 'Factory::class' pages/admin -g '*.php' || true) | wc -l | tr -d '[:space:]')"
|
||||
c8="$( (rg -n 'ApiResponse::readJsonBody\\(' pages/api/v1 -g '*.php' || true) | wc -l | tr -d '[:space:]')"
|
||||
|
||||
if [[ "${c1}" == "0" && "${c2}" == "0" && "${c3}" == "0" && "${c4}" == "0" && "${c5}" == "0" && "${c6}" == "0" && "${c7}" == "0" && "${c8}" == "0" ]]; then
|
||||
echo "[OK] QG-004 Structural checks clean"
|
||||
else
|
||||
warn "QG-004 Structural checks found potential violations (non-blocking): ${c1}/${c2}/${c3}/${c4}/${c5}/${c6}/${c7}/${c8}"
|
||||
fi
|
||||
else
|
||||
warn "QG-004 skipped: rg is not installed"
|
||||
fi
|
||||
|
||||
# QG-007 (non-blocking): periodic dependency hygiene
|
||||
if docker compose exec -T php vendor/bin/composer-unused; then
|
||||
echo "[OK] QG-007 composer-unused"
|
||||
else
|
||||
warn "QG-007 composer-unused reported issues (non-blocking in phase 1)"
|
||||
fi
|
||||
|
||||
# QG-005 (manual, non-blocking)
|
||||
warn "QG-005 manual step required: Browser smoke with DevTools console (expect no new JS errors)."
|
||||
|
||||
echo "[OK] Extended QA completed (required gates already passed, optional gates reported)."
|
||||
44
bin/qa-required.sh
Executable file
44
bin/qa-required.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd -- "${script_dir}/.." && pwd)"
|
||||
cd "${repo_root}"
|
||||
|
||||
run_step() {
|
||||
local label="$1"
|
||||
shift
|
||||
echo "[RUN] ${label}"
|
||||
"$@"
|
||||
echo "[OK] ${label}"
|
||||
}
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "[ERROR] docker is required." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
docker compose version >/dev/null 2>&1 || {
|
||||
echo "[ERROR] docker compose is required." >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
run_step "QG-001 PHPUnit" \
|
||||
docker compose exec -T php vendor/bin/phpunit
|
||||
|
||||
run_step "QG-002 PHPStan" \
|
||||
docker compose exec -T php vendor/bin/phpstan analyse -c phpstan.neon --no-progress
|
||||
|
||||
run_step "QG-003 Architecture Core Contract" \
|
||||
docker compose exec -T php vendor/bin/phpunit tests/Architecture/CoreStarterkitContractTest.php
|
||||
|
||||
run_step "QG-006 PHP Style Check" \
|
||||
docker compose exec -T php vendor/bin/php-cs-fixer fix --config=tools/php-cs-fixer/.php-cs-fixer.dist.php --dry-run --diff --verbose
|
||||
|
||||
run_step "QG-008 Docs link integrity" \
|
||||
bin/docs-link-check.sh
|
||||
|
||||
run_step "QG-009 Codex skills sync" \
|
||||
bin/codex-skills-sync.sh --check
|
||||
|
||||
echo "[OK] Required QA gates passed (QG-001/002/003/006/008/009)."
|
||||
Reference in New Issue
Block a user