Moves the agent workflow system from agent-system/ to .agents/ (dotfile convention). Restructured from 5-role to 7-role pipeline: adds Analyst and splits Reviewer into Code Reviewer + Security Reviewer. Removes all old workflow run artifacts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
160 lines
6.8 KiB
JSON
160 lines
6.8 KiB
JSON
{
|
|
"version": "2.0.0",
|
|
"guards": [
|
|
{
|
|
"id": "GR-CORE-003",
|
|
"area": "core",
|
|
"reviewer": "code",
|
|
"title": "Request input contract",
|
|
"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."
|
|
},
|
|
{
|
|
"id": "GR-CORE-011",
|
|
"area": "core",
|
|
"reviewer": "code",
|
|
"title": "Settings in DB, not config files",
|
|
"requirement": "New application settings MUST be stored in the settings DB table. config/settings.php is a partial hot-path cache only."
|
|
},
|
|
{
|
|
"id": "GR-CORE-012",
|
|
"area": "core",
|
|
"reviewer": "code",
|
|
"title": "POST-Redirect-GET",
|
|
"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."
|
|
}
|
|
]
|
|
}
|