docs: harden CLAUDE.md with mandatory workflow, security guards, and anti-patterns
Surface binding rules from .agents/ (guards, quality gates, security) directly in CLAUDE.md so they are enforced from conversation start. Adds: Mandatory Workflow section, Security (non-negotiable) section, Never Do This anti-patterns, module isolation constraints, and structured quality gate table with gate IDs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
72
CLAUDE.md
72
CLAUDE.md
@@ -2,7 +2,15 @@
|
||||
|
||||
Multi-tenant admin application built on MintyPHP. Manages tenants, users, departments, roles, permissions, address books, mail, CSV imports, scheduled jobs, and Microsoft Entra ID SSO.
|
||||
|
||||
> **Agent workflow:** guards, quality gates, role prompts, contracts, and skills live in `.agents/` — start with `.agents/README.md`.
|
||||
## Mandatory Workflow
|
||||
|
||||
All guard IDs (GR-\*) and gate IDs (QG-\*) from `.agents/checks/` are **binding — not advisory**.
|
||||
|
||||
- **Any change touching >1 layer or adding a new feature** MUST follow the `.agents/workflow.md` state machine (Analyst → Planner → Executor → Reviewers → Finalizer). Read `.agents/README.md` and the relevant role prompt in `.agents/prompts/` before starting.
|
||||
- **Quick fixes** (single-file typo, translation update, CSS tweak) may skip the full workflow but MUST still pass mandatory quality gates (QG-001, QG-002, QG-003, QG-006).
|
||||
- **New modules** MUST conform to `.agents/contracts/module-manifest.schema.json` and pass all 9 security guards (GR-SEC-001 through GR-SEC-009).
|
||||
|
||||
Full workflow definition: `.agents/workflow.md` | Guard catalog: `.agents/checks/guard-catalog.json` | Skills: `.agents/skills/`
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -113,6 +121,10 @@ docker/ # Dockerfiles, Nginx configs, PHP configs
|
||||
- **Runtime sync:** `php bin/module-runtime-sync.php` after any module/manifest change (builds page symlinks, syncs permissions, publishes assets)
|
||||
- **Fingerprint guard:** `web/index.php` validates runtime state matches active modules; fails fast if stale
|
||||
- **API isolation:** API requests (`api/` prefix) skip session/auth/cookie flows entirely; modules using API endpoints rely on `ApiBootstrap.php`
|
||||
- **Cross-module coupling:** Modules may depend on other modules but MUST declare `requires: [<module-id>]` in their manifest. Undeclared cross-module imports are forbidden. Prefer loose coupling via events and providers over direct service injection
|
||||
- **Module DB changes:** Via `module:migrate`, not `db/updates/` (which is for core schema only)
|
||||
- **Module permissions:** Registered in manifest, synced via `module:permissions-sync` — never hardcoded
|
||||
- **Manifest contract:** Must conform to `.agents/contracts/module-manifest.schema.json`
|
||||
|
||||
### Routing
|
||||
|
||||
@@ -126,9 +138,13 @@ docker/ # Dockerfiles, Nginx configs, PHP configs
|
||||
### PHP Conventions
|
||||
|
||||
- PSR-4 autoload: `MintyPHP\` → `lib/`, `MintyPHP\Module\*` → `modules/*/lib/`, `MintyPHP\Tests\` → `tests/`
|
||||
- All user-facing text uses `t('key')` translation helper
|
||||
- All user-facing text uses `t('key')` translation helper — keys must exist in all language files under `i18n/`
|
||||
- Request input via `requestInput()` — never raw `$_GET`/`$_POST`/`$_SESSION` (GR-CORE-003)
|
||||
- Permissions + tenant scope enforced in actions/services, never just in UI
|
||||
- Security/integration settings stay in DB, not in `config/settings.php` file cache
|
||||
- Security/integration settings stay in DB, not in `config/settings.php` file cache (GR-CORE-011)
|
||||
- POST-Redirect-GET (PRG) pattern on form submissions; flash before redirect (GR-CORE-012)
|
||||
- Constructor injection for dependencies; no hidden global state (GR-TEST-002)
|
||||
- New/changed Service or Gateway must have PHPUnit tests — happy path + edge case (GR-TEST-001)
|
||||
|
||||
### Frontend Conventions
|
||||
|
||||
@@ -143,21 +159,59 @@ docker/ # Dockerfiles, Nginx configs, PHP configs
|
||||
- Edit pages: tabs → `Master data` | `Visibility` | optional `Danger zone`
|
||||
- Titlebar partial for primary actions (Save, Save & close)
|
||||
- Secondary actions in Aside block via `app-details-aside-actions.phtml`
|
||||
- Lists use Grid.js
|
||||
- Lists use Grid.js via `initStandardListPage()` (GR-UI-LIST)
|
||||
- Detail pages use shared partials and layout contracts (GR-UI-DETAIL)
|
||||
- New views must handle loading, empty, error, and success states (GR-UI-014)
|
||||
- All visible text wrapped in `t('...')`
|
||||
- Check existing JS/CSS components before adding new ones (GR-UI-REUSE)
|
||||
|
||||
### Never Do This
|
||||
|
||||
- Direct `$_GET`/`$_POST`/`$_SESSION` access — use `requestInput()` (GR-CORE-003)
|
||||
- SQL outside Repository classes (GR-SEC-003)
|
||||
- `new Service()` or `new Gateway()` outside Factory classes (GR-TEST-002)
|
||||
- Hardcoding module UI into core templates — use platform slots
|
||||
- Core schema changes without idempotent `db/updates/` script (GR-CORE-010)
|
||||
- Settings in config files instead of DB `settings` table (GR-CORE-011)
|
||||
- Skipping PRG pattern on form submissions (GR-CORE-012)
|
||||
- Loading assets from external CDNs (GR-SEC-004)
|
||||
- Undeclared cross-module imports (must use `requires` in manifest)
|
||||
- Inline SQL or string-concatenated queries (GR-SEC-003)
|
||||
- OpenAPI changes without updating the spec (GR-CORE-007)
|
||||
|
||||
## Database
|
||||
|
||||
- Schema defined in `db/init/init.sql` (applied once on container init)
|
||||
- No migration framework — schema changes for existing installs are idempotent SQL scripts
|
||||
- No migration framework — core schema changes for existing installs are idempotent SQL scripts in `db/updates/`
|
||||
- Module schema changes via `module:migrate` (separate from core)
|
||||
- Settings stored in `settings` DB table (single source of truth); `config/settings.php` is a partial file cache for hot-path UI reads only
|
||||
|
||||
## Security (non-negotiable)
|
||||
|
||||
These rules are enforced by guards GR-SEC-001 through GR-SEC-009 in `.agents/checks/guard-catalog.json`. Any violation is a blocking finding.
|
||||
|
||||
- CSRF token verified on every POST (GR-SEC-001)
|
||||
- No PII or secrets in logs or audit metadata (GR-SEC-002)
|
||||
- SQL only via Repository prepared statements — no inline queries (GR-SEC-003)
|
||||
- No external CDN or remote asset loading (GR-SEC-004)
|
||||
- Encryption only via `lib/Support/Crypto.php` AES-256-GCM (GR-SEC-005)
|
||||
- File uploads: `storage/` only, authz-gated serving, MIME-validated (GR-SEC-006)
|
||||
- API requests must not start sessions (GR-SEC-007)
|
||||
- Authorization enforced server-side, not just in UI (GR-SEC-008)
|
||||
- Tenant scope (`tenant_id`) enforced on all queries — no unscoped data access (GR-SEC-009)
|
||||
|
||||
## Quality Gates
|
||||
|
||||
- **PHPStan level 5** — scans `config/`, `lib/`, `modules/`, `pages/`, `tests/`
|
||||
- **PHPUnit 11** — bootstrap: `tests/bootstrap.php`
|
||||
- **Frontend Smoke-Check** — browser console bleibt fehlerfrei in Kernflows
|
||||
- **composer-unused** — periodic check for unused dependencies
|
||||
9 gates defined in `.agents/checks/quality-gates.json`. **Mandatory before any merge:**
|
||||
|
||||
| ID | Gate | Command |
|
||||
|---|---|---|
|
||||
| QG-001 | PHPUnit | `vendor/bin/phpunit` |
|
||||
| QG-002 | PHPStan level 5 | `vendor/bin/phpstan analyse -c phpstan.neon` |
|
||||
| QG-003 | Architecture Contract | `vendor/bin/phpunit tests/Architecture/CoreStarterkitContractTest.php` |
|
||||
| QG-006 | PHP Style | `composer cs:check` |
|
||||
|
||||
Additional gates (fast/periodic): QG-004 structural checks, QG-005 JS smoke, QG-007 composer-unused, QG-008 docs links, QG-009 skills sync. See gate catalog for details.
|
||||
|
||||
## Environment
|
||||
|
||||
|
||||
Reference in New Issue
Block a user