agent foundation
This commit is contained in:
272
agent-system/checks/guard-catalog.json
Normal file
272
agent-system/checks/guard-catalog.json
Normal file
@@ -0,0 +1,272 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"source_skill": "tools/codex-skills/core-guardrails/SKILL.md",
|
||||
"guards": [
|
||||
{
|
||||
"id": "GR-CORE-001",
|
||||
"area": "core",
|
||||
"title": "Layering boundaries",
|
||||
"requirement": "MUST keep pages orchestration-only and business logic in services.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-002",
|
||||
"area": "core",
|
||||
"title": "No direct service instantiation in pages",
|
||||
"requirement": "MUST NOT instantiate Service, Gateway or Repository directly in pages.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-003",
|
||||
"area": "core",
|
||||
"title": "Request input contract",
|
||||
"requirement": "MUST read input via requestInput in pages and avoid superglobals for request data.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-004",
|
||||
"area": "core",
|
||||
"title": "API json body contract",
|
||||
"requirement": "MUST NOT use ApiResponse::readJsonBody in pages/api/v1.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-005",
|
||||
"area": "security",
|
||||
"title": "Server-side authz",
|
||||
"requirement": "MUST enforce authorization server-side.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-006",
|
||||
"area": "security",
|
||||
"title": "Server-side tenant scope",
|
||||
"requirement": "MUST enforce tenant scope server-side.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-007",
|
||||
"area": "api",
|
||||
"title": "OpenAPI sync",
|
||||
"requirement": "MUST update OpenAPI in same merge when API changes.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-001",
|
||||
"area": "ui",
|
||||
"title": "List initialization standard",
|
||||
"requirement": "MUST initialize lists via initStandardListPage.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-002",
|
||||
"area": "ui",
|
||||
"title": "No legacy filter toggle markup",
|
||||
"requirement": "MUST NOT introduce legacy filter toggle attributes.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-003",
|
||||
"area": "ui",
|
||||
"title": "Row interaction standard",
|
||||
"requirement": "MUST preserve row action column plus enter and dblclick fallback behavior.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-004",
|
||||
"area": "ui",
|
||||
"title": "Page size standard",
|
||||
"requirement": "MUST preserve page size options and URL/localStorage/default precedence.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-005",
|
||||
"area": "ui",
|
||||
"title": "Detail page standard",
|
||||
"requirement": "MUST use standard detail page contracts for dirty-state and actions.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-006",
|
||||
"area": "ui",
|
||||
"title": "No inline confirm",
|
||||
"requirement": "MUST NOT use inline confirm handlers on standardized detail flows.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-007",
|
||||
"area": "ui",
|
||||
"title": "Shared partial usage",
|
||||
"requirement": "MUST use shared list and detail partials for standardized UI blocks.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-016",
|
||||
"area": "ui",
|
||||
"title": "Template structure discipline for new features",
|
||||
"requirement": "New pages MUST use the established layout system (templates/default.phtml or a named layout variant). UI blocks that appear in two or more pages MUST be extracted as a partial under templates/partials/ rather than duplicated inline. New partials MUST follow the naming convention app-{context}-{purpose}.phtml. Page-specific rendering belongs in pages/*.phtml, not in templates/. MUST NOT create ad-hoc layout HTML inside pages that bypasses the layout system.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-008",
|
||||
"area": "ui",
|
||||
"title": "Template RBAC contract",
|
||||
"requirement": "MUST use viewAuth in templates and avoid can calls.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-009",
|
||||
"area": "ui",
|
||||
"title": "No a11y regression",
|
||||
"requirement": "MUST NOT introduce regressions in accessibility basics (labels, roles, keyboard focus) on touched flows.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-008",
|
||||
"area": "core",
|
||||
"title": "No direct superglobal access in pages",
|
||||
"requirement": "MUST NOT use $_SESSION, $_SERVER, $_COOKIE, $_ENV directly in pages; use framework abstractions (app(SessionStoreInterface::class), RequestContext, requestInput()) instead.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-001",
|
||||
"area": "security",
|
||||
"title": "CSRF verification on POST endpoints",
|
||||
"requirement": "MUST verify CSRF token on every POST endpoint in pages before processing the request body.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-002",
|
||||
"area": "security",
|
||||
"title": "No unredacted PII or secrets in logs and audit metadata",
|
||||
"requirement": "MUST NOT write PII (email, names, UUIDs) or secrets (tokens, passwords) to logs or audit metadata without prior redaction.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-003",
|
||||
"area": "security",
|
||||
"title": "SQL via Repository with prepared statements only",
|
||||
"requirement": "MUST NOT build SQL strings with user-controlled input; all queries MUST go through Repository classes using prepared statements.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-LANG-001",
|
||||
"area": "lang",
|
||||
"title": "PSR-4 namespace alignment",
|
||||
"requirement": "MUST align PHP namespace with directory path (MintyPHP\\ → lib/, MintyPHP\\Tests\\ → tests/); violations are caught by QG-003.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-LANG-002",
|
||||
"area": "lang",
|
||||
"title": "PHP style compliance",
|
||||
"requirement": "MUST pass composer cs:check without diff (php-cs-fixer dry-run); fix with composer cs:fix before merge.",
|
||||
"source": "tools/codex-skills/starterkit-php-style-ci/SKILL.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-TEST-001",
|
||||
"area": "test",
|
||||
"title": "Tests ship with new logic",
|
||||
"requirement": "New or changed business logic in lib/Service/ MUST be accompanied by PHPUnit tests in the same merge covering the happy path and at least one failure or edge case. No new public method in a Service or Gateway without a test.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-TEST-002",
|
||||
"area": "test",
|
||||
"title": "Code must be unit-testable",
|
||||
"requirement": "New code MUST use constructor injection for all dependencies. MUST NOT introduce static side-effects in constructors, hidden global state, or direct DB/HTTP calls outside Repository/Gateway abstractions — patterns that make unit testing without mocks impossible.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-010",
|
||||
"area": "core",
|
||||
"title": "DB schema changes for existing installs must be idempotent SQL scripts in db/updates/",
|
||||
"requirement": "Any schema or data change for existing installations MUST be shipped as an idempotent SQL script in db/updates/ (e.g. using IF NOT EXISTS, ON DUPLICATE KEY, or guarded ALTER TABLE). MUST NOT modify db/init/init.sql only — existing containers will not re-run init.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-011",
|
||||
"area": "core",
|
||||
"title": "New settings belong in the DB settings table, not in config files",
|
||||
"requirement": "New application settings MUST be stored in the settings DB table as the single source of truth. config/settings.php is a partial hot-path cache only and MUST NOT be used as primary storage for new settings. Security, integration, and feature-flag settings MUST go through the settings gateway layer.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-012",
|
||||
"area": "core",
|
||||
"title": "POST-Redirect-GET after successful mutating actions",
|
||||
"requirement": "Actions that successfully mutate state (create, update, delete) MUST respond with a redirect (PRG pattern) rather than rendering a response directly. This prevents double-submit on browser reload. Flash messages MUST be set before the redirect via Flash::set().",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-CORE-009",
|
||||
"area": "core",
|
||||
"title": "Repository list queries must use RepoQuery::sanitizeLimitOffset",
|
||||
"requirement": "New Repository methods that return lists MUST use RepoQuery::sanitizeLimitOffset() to enforce LIMIT and OFFSET. Unbounded SELECT queries without LIMIT on potentially large tables are forbidden. The default maxLimit of 100 MUST NOT be raised without explicit justification reviewed and approved.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-006",
|
||||
"area": "security",
|
||||
"title": "User-uploaded files stored in storage/, never in web/",
|
||||
"requirement": "Files uploaded by users MUST be stored under storage/ (e.g. storage/users/{uuid}/, storage/tenants/{uuid}/, storage/imports/) and MUST NOT be written to web/ or any other publicly served directory. Storage paths MUST use non-guessable identifiers (UUID v4 or equivalent) to prevent enumeration. Files MUST be served through a PHP controller that enforces authorization, not directly by the web server. MUST validate file type (MIME + extension allowlist) before storing.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-005",
|
||||
"area": "security",
|
||||
"title": "Encryption only via lib/Support/Crypto.php",
|
||||
"requirement": "Any encryption or decryption of sensitive data MUST use the Crypto class (lib/Support/Crypto.php) which provides AES-256-GCM via APP_CRYPTO_KEY. MUST NOT use raw openssl_encrypt/openssl_decrypt, base64 encoding as a substitute for encryption, or any other hand-rolled crypto primitives.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-core.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-SEC-004",
|
||||
"area": "security",
|
||||
"title": "No external CDN or remote asset loading",
|
||||
"requirement": "MUST NOT load JS, CSS, fonts, or any other assets from external CDNs (Cloudflare, jsDelivr, unpkg, Google Fonts, etc.) or remote URLs in templates, pages, or layout files. If a third-party library is required it MUST be vendored locally in the repository (e.g. web/js/vendor/ or web/css/vendor/) and served via assetVersion(). No <script src='https://...'>, <link href='https://...'>, @import url('https://...'), or fetch() calls to external asset hosts.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-014",
|
||||
"area": "ui",
|
||||
"title": "UI state completeness for new views and components",
|
||||
"requirement": "New user-facing views or components that display data or trigger actions MUST handle all four states: loading (progress indicator while data is fetched), empty (explicit message when no data exists), error (user-visible error feedback when an action or data load fails), and success (confirmation after a completed action). All four states MUST be defined in the plan before implementation starts. Applies to new views and components; not required for small, isolated fixes to existing UI.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-013",
|
||||
"area": "ui",
|
||||
"title": "A11y by design: new interactive components built accessible from the start",
|
||||
"requirement": "New interactive UI components (buttons, links, forms, modals, dropdowns, custom controls) MUST use semantic HTML elements. MUST be fully keyboard-operable (Tab order, Enter/Space to activate, Escape to close overlays, no keyboard trap). MUST use ARIA attributes only where semantic HTML is insufficient — no ARIA-spam. MUST meet WCAG 2.1 AA color contrast for any newly introduced text or icon elements. These requirements apply at creation time, not as a post-hoc retrofit.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-015",
|
||||
"area": "ui",
|
||||
"title": "i18n key completeness: all language files updated in the same merge",
|
||||
"requirement": "Every new translation key added via t('key') MUST be present in ALL language files (i18n/default_de.json and i18n/default_en.json) in the same merge. A key present in one file but missing in another causes visible fallback output. MUST NOT leave placeholder or empty string values without a TODO comment.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-010",
|
||||
"area": "ui",
|
||||
"title": "i18n: all visible text must use t()",
|
||||
"requirement": "MUST wrap all user-visible strings in phtml views with t('key'). MUST NOT hardcode display strings in templates or partials.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-011",
|
||||
"area": "ui",
|
||||
"title": "JS reuse-first: prefer existing exports over new functions",
|
||||
"requirement": "MUST check web/js/core/ and web/js/components/ for existing exported functions before adding a new one. A new export is only justified when no existing function covers the use-case after review. MUST NOT duplicate logic already present in app-dom.js, app-grid-factory.js, app-detail-page-factory.js, or other core modules.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
},
|
||||
{
|
||||
"id": "GR-UI-012",
|
||||
"area": "ui",
|
||||
"title": "CSS reuse-first: prefer existing classes over new rules",
|
||||
"requirement": "MUST check existing CSS layers (base, components, layout, pages) for suitable classes before writing new rules. MUST use existing app-* component classes as the basis and only add additive overrides. MUST NOT duplicate declarations already defined in shared component or layout files.",
|
||||
"source": "tools/codex-skills/core-guardrails/references/boundaries-ui.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user