# Guard Checklist

Use this checklist for the guard reviewer.
Canonical guard IDs live in `agent-system/checks/guard-catalog.json`.

## Architecture
- `GR-CORE-001` no boundary violations against project layering
- `GR-CORE-002` no direct bypass of shared factories/services where prohibited
- `GR-CORE-003` request input contract is respected (requestInput(), no $_POST/$_GET/$_FILES/REQUEST_METHOD)
- `GR-CORE-004` API json body contract is respected
- `GR-CORE-008` no direct superglobal access in pages ($_SESSION, $_SERVER, $_COOKIE, $_ENV)
- `GR-CORE-009` new Repository list methods use RepoQuery::sanitizeLimitOffset(); no unbounded SELECTs on large tables; maxLimit 100 not raised without justification
- `GR-CORE-010` DB schema changes for existing installs shipped as idempotent SQL scripts in db/updates/; db/init/init.sql alone is not sufficient
- `GR-CORE-011` new settings stored in DB settings table via settings gateway; config/settings.php is hot-path cache only, not primary storage
- `GR-CORE-012` successful mutating POSTs respond with redirect (PRG); flash messages set before redirect via Flash::set()

## Security
- `GR-CORE-005` auth and permission checks stay intact
- `GR-CORE-006` tenant-scope checks stay intact
- `GR-SEC-001` CSRF token verified on every POST endpoint before request body processing
- `GR-SEC-002` no unredacted PII or secrets in logs and audit metadata
- `GR-SEC-003` all SQL goes through Repository with prepared statements; no string-interpolated queries
- `GR-SEC-004` no external CDN or remote asset loading; all JS/CSS/fonts must be vendored locally and served via assetVersion()
- `GR-SEC-005` encryption only via lib/Support/Crypto.php (AES-256-GCM); no raw openssl_encrypt, no base64-as-encryption, no hand-rolled crypto
- `GR-SEC-006` user-uploaded files stored under storage/{type}/{uuid}/ only; never written to web/; served via PHP controller with authz check; MIME + extension validated before storage

## Frontend and UX
- `GR-UI-001` list initialization standard is preserved
- `GR-UI-002` no legacy filter toggle markup introduced
- `GR-UI-003` row interaction standard is preserved where applicable
- `GR-UI-004` page size standard is preserved where applicable
- `GR-UI-005` detail page standard is preserved where applicable
- `GR-UI-006` no inline confirm hacks
- `GR-UI-007` shared partial usage remains consistent (existing partials reused where applicable)
- `GR-UI-016` template structure discipline: new pages use established layout system; blocks reused in ≥2 pages extracted as partial in templates/partials/ with naming app-{context}-{purpose}.phtml; no ad-hoc layout HTML in pages that bypasses the layout system
- `GR-UI-008` template RBAC contract remains consistent
- `GR-UI-009` no regression in a11y basics (labels, roles, keyboard focus) for touched flows
- `GR-UI-013` a11y by design: new interactive components use semantic HTML, are keyboard-operable (Tab/Enter/Escape), use ARIA only where necessary, meet WCAG 2.1 AA contrast
- `GR-UI-014` UI state completeness: new views/components define and implement loading, empty, error, and success states before implementation starts
- `GR-UI-010` all user-visible strings in phtml views wrapped in t(); no hardcoded display strings
- `GR-UI-015` new t() keys present in all language files (de + en) in the same merge; no key missing in any language file
- `GR-UI-011` JS reuse-first: existing exports in web/js/core/ and web/js/components/ checked before adding a new function; no logic duplication from core modules
- `GR-UI-012` CSS reuse-first: existing app-* classes and layer rules checked before writing new declarations; only additive overrides on top of shared components

## Testing
- `GR-TEST-001` new or changed Service/Gateway logic has accompanying PHPUnit tests (happy path + at least one failure/edge case) in the same merge
- `GR-TEST-002` new code uses constructor injection; no static side-effects, hidden global state, or untestable DB/HTTP calls outside Repository/Gateway abstractions

## Language and Style
- `GR-LANG-001` PSR-4 namespace/directory alignment is intact (verified by QG-003)
- `GR-LANG-002` PHP style passes composer cs:check without diff for touched files

## Quality Gates
- `QG-001` to `QG-003` are run unless explicitly out of scope
- `QG-004` fast structural checks reported when relevant
- `QG-005` JS smoke performed for JS-touching changes; no new unhandled runtime errors
- `QG-006` PHP style check run for any PHP-touching changes
- `QG-007` composer-unused run periodically; any newly unused package flagged to reviewer

References:
- `tools/codex-skills/core-guardrails/references/boundaries-core.md`
- `tools/codex-skills/core-guardrails/references/boundaries-ui.md`
- `tools/codex-skills/core-guardrails/references/quality-gates.md`
- `tools/codex-skills/starterkit-grid-standards/SKILL.md`
- `tools/codex-skills/starterkit-php-style-ci/SKILL.md`
