chore(agents): implement v2 hardening and enforcement-ready QA

This commit is contained in:
2026-04-01 19:41:56 +02:00
parent 7121732fcf
commit dba589b495
31 changed files with 1349 additions and 78 deletions

24
bin/dev
View File

@@ -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
View 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
View 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)."