"requirement":"MUST read input via requestInput() in pages and avoid superglobals for request data."
},
{
"id":"GR-CORE-007",
"area":"core",
"reviewer":"code",
"title":"OpenAPI sync",
"requirement":"MUST update docs/openapi.yaml in the same merge when API endpoints change."
},
{
"id":"GR-CORE-010",
"area":"core",
"reviewer":"code",
"title":"Idempotent DB update scripts",
"requirement":"Schema or data changes for existing installs MUST be shipped as idempotent SQL scripts in db/updates/ (IF NOT EXISTS, ON DUPLICATE KEY, guarded ALTER TABLE). db/init/init.sql alone is not sufficient."
"requirement":"Actions that successfully mutate state MUST respond with a redirect (PRG pattern). Flash messages set before redirect via Flash::set()."
},
{
"id":"GR-TEST-001",
"area":"test",
"reviewer":"code",
"title":"Tests ship with new logic",
"requirement":"New or changed business logic in lib/Service/ MUST be accompanied by PHPUnit tests covering the happy path and at least one failure or edge case. No new public method in a Service or Gateway without a test."
},
{
"id":"GR-TEST-002",
"area":"test",
"reviewer":"code",
"title":"Code must be testable",
"requirement":"New code MUST use constructor injection. MUST NOT introduce static side-effects in constructors, hidden global state, or direct DB/HTTP calls outside Repository/Gateway abstractions."
},
{
"id":"GR-UI-014",
"area":"ui",
"reviewer":"code",
"title":"UI state completeness",
"requirement":"New user-facing views or components MUST handle four states: loading, empty, error, success. All four defined in plan before implementation. Not required for small fixes to existing UI."
},
{
"id":"GR-UI-LIST",
"area":"ui",
"reviewer":"code",
"title":"List and grid standards",
"requirement":"Lists MUST preserve row action column plus enter/dblclick fallback behavior. Page size options and URL/localStorage/default precedence MUST be maintained. New lists MUST use initStandardListPage()."
},
{
"id":"GR-UI-DETAIL",
"area":"ui",
"reviewer":"code",
"title":"Detail page standards",
"requirement":"MUST use standard detail page contracts for dirty-state and actions. MUST NOT use inline confirm handlers on standardized flows. MUST use shared list/detail partials for standardized UI blocks. New pages MUST use the established layout system. Blocks reused in 2+ pages MUST be extracted as partials (app-{context}-{purpose}.phtml)."
},
{
"id":"GR-UI-A11Y",
"area":"ui",
"reviewer":"code",
"title":"Accessibility",
"requirement":"MUST NOT regress a11y basics (labels, roles, keyboard focus) on touched flows. New interactive components MUST use semantic HTML, be keyboard-operable (Tab/Enter/Escape), use ARIA only where necessary, and meet WCAG 2.1 AA contrast."
},
{
"id":"GR-UI-I18N",
"area":"ui",
"reviewer":"code",
"title":"Internationalization completeness",
"requirement":"All user-visible strings in phtml views MUST use t('key'). Every new t() key MUST be present in ALL language files (i18n/default_de.json and i18n/default_en.json) in the same merge."
},
{
"id":"GR-UI-REUSE",
"area":"ui",
"reviewer":"code",
"title":"Reuse-first (JS + CSS)",
"requirement":"MUST check web/js/core/ and web/js/components/ for existing exports before adding new functions. MUST check existing CSS layers and app-* classes before writing new rules. No duplication of logic from core modules."
},
{
"id":"GR-SEC-001",
"area":"security",
"reviewer":"security",
"title":"CSRF on POST",
"requirement":"MUST verify CSRF token on every POST endpoint in pages before processing the request body."
},
{
"id":"GR-SEC-002",
"area":"security",
"reviewer":"security",
"title":"No PII/secrets in logs",
"requirement":"MUST NOT write PII (email, names, UUIDs) or secrets (tokens, passwords) to logs or audit metadata without prior redaction."
},
{
"id":"GR-SEC-003",
"area":"security",
"reviewer":"security",
"title":"SQL via prepared statements only",
"requirement":"MUST NOT build SQL strings with user-controlled input. All queries MUST go through Repository classes using prepared statements."
},
{
"id":"GR-SEC-004",
"area":"security",
"reviewer":"security",
"title":"No external CDN/remote assets",
"requirement":"MUST NOT load JS, CSS, fonts from external CDNs or remote URLs. Third-party libraries MUST be vendored locally and served via assetVersion()."
},
{
"id":"GR-SEC-005",
"area":"security",
"reviewer":"security",
"title":"Encryption via Crypto only",
"requirement":"Encryption/decryption MUST use lib/Support/Crypto.php (AES-256-GCM). No raw openssl_encrypt, no base64 as encryption, no hand-rolled crypto."
},
{
"id":"GR-SEC-006",
"area":"security",
"reviewer":"security",
"title":"File uploads in storage/ only",
"requirement":"User-uploaded files MUST be stored under storage/ with non-guessable identifiers. MUST NOT be written to web/. MUST be served via PHP controller with authz. MUST validate MIME + extension before storing."
},
{
"id":"GR-SEC-007",
"area":"security",
"reviewer":"security",
"title":"API must not start sessions",
"requirement":"API requests (api/ prefix) MUST NOT trigger Session::start(), remember-me cookie handling, or session timeout redirects."
},
{
"id":"GR-SEC-008",
"area":"security",
"reviewer":"security",
"title":"Server-side authorization",
"requirement":"MUST enforce authorization server-side in actions and services. UI-only permission checks are insufficient."
},
{
"id":"GR-SEC-009",
"area":"security",
"reviewer":"security",
"title":"Server-side tenant scope",
"requirement":"MUST enforce tenant scope server-side. Every query touching tenant-scoped data MUST filter by tenant_id. No cross-tenant data leakage."
"requirement":"Views (.phtml) MUST use e() for all HTML output. Raw echo is only permitted for pre-built HTML fragments from framework helpers (e.g. ARIA attributes from navActive()). Each raw echo MUST carry an inline '// raw-html-ok: reason' comment."
"requirement":"MUST enforce strict layer separation: Views render only (no DB calls), Services contain no HTML, Repositories are isolated from HTTP/session. No cross-layer violations."
},
{
"id":"GR-CORE-MODULE",
"area":"core",
"reviewer":"code",
"title":"Module boundary isolation",
"requirement":"Modules MUST use MintyPHP\\Module\\* namespaces, declare valid manifests conforming to the schema, register providers correctly, prefix session keys with module.<id>.*, and pass per-module isolation tests."
},
{
"id":"GR-CORE-META",
"area":"core",
"reviewer":"code",
"title":"Agent and codex system integrity",
"requirement":"Guard catalog, enforcement map, quality gates, agent references, and codex skill/docs links MUST be internally consistent. All guard/gate IDs MUST resolve. No orphaned or broken references."
},
{
"id":"GR-UI-TAXONOMY",
"area":"ui",
"reviewer":"code",
"title":"Status taxonomy consistency",
"requirement":"Status enums, filter schemas, data-layer constants, and UI labels MUST stay in sync across all layers. No literal status strings outside taxonomy enums."