refactor: rename lib/ to core/ for clearer core-module separation

Rename the top-level lib/ directory to core/ so the project root
immediately communicates which code is core platform and which lives
in modules/. PHP namespaces (MintyPHP\*) are unchanged — only the
Composer PSR-4 path mapping moves from lib/ to core/.

Module-internal lib/ directories (modules/*/lib/) are untouched.

Updated across the full stack:
- composer.json PSR-4 mapping
- bootstrap entry points (web/index.php, bin/*, tests/bootstrap.php)
- tooling configs (phpstan.neon, phpunit.xml, php-cs-fixer)
- 26 architecture contract tests
- enforcement-policy, guard-catalog, quality-gates
- all documentation (CLAUDE.md, README, 25 docs/, .agents/skills/)
- bin/qa-extended.sh search paths
- .claude/settings.local.json permission paths

Workflow: .agents/runs/CORE-LIB-RENAME-001/ (Analyst → Planner →
Executor → Code Review (4 findings fixed) → Security Review →
Acceptance Test → Finalizer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 23:20:05 +02:00
parent 7c10fadcb9
commit 0e86925464
371 changed files with 191 additions and 192 deletions

View File

@@ -6,9 +6,9 @@
"id": "risk-security",
"description": "Any change touching authentication, authorization, CSRF, encryption, logging redaction, file uploads, or API bootstrap/security behavior.",
"paths": [
"lib/Http/**",
"lib/Service/Access/**",
"lib/Support/Crypto.php",
"core/Http/**",
"core/Service/Access/**",
"core/Support/Crypto.php",
"pages/api/**",
"pages/**"
]
@@ -17,7 +17,7 @@
"id": "risk-data-boundary",
"description": "Any change touching tenant-scoped data access, repository query boundaries, DB schema updates, or API contracts.",
"paths": [
"lib/Repository/**",
"core/Repository/**",
"db/updates/**",
"db/init/init.sql",
"docs/openapi.yaml"
@@ -28,7 +28,7 @@
"description": "Any change touching module manifests, module runtime wiring, module routes, module providers, or module migrations/assets.",
"paths": [
"modules/*/module.php",
"lib/App/Module/**",
"core/App/Module/**",
"storage/runtime/pages/**",
"web/modules/**"
]
@@ -37,7 +37,7 @@
"id": "risk-cross-layer",
"description": "Any feature/addition changing more than one architecture layer (Repository, Service, pages/templates/web, modules, config, db).",
"paths": [
"lib/**",
"core/**",
"pages/**",
"templates/**",
"web/**",

View File

@@ -41,7 +41,7 @@
"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."
"requirement": "New or changed business logic in core/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",
@@ -125,7 +125,7 @@
"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."
"requirement": "Encryption/decryption MUST use core/Support/Crypto.php (AES-256-GCM). No raw openssl_encrypt, no base64 as encryption, no hand-rolled crypto."
},
{
"id": "GR-SEC-006",

View File

@@ -38,7 +38,7 @@ Guard IDs live in `.agents/checks/guard-catalog.json` (guards where `reviewer` =
- `GR-SEC-002` no PII or secrets in logs/audit metadata
- `GR-SEC-003` all SQL via Repository with prepared statements
- `GR-SEC-004` no external CDN or remote asset loading
- `GR-SEC-005` encryption only via lib/Support/Crypto.php
- `GR-SEC-005` encryption only via core/Support/Crypto.php
- `GR-SEC-006` file uploads in storage/ only; authz-gated serving; MIME validated
- `GR-SEC-007` API requests do not start sessions
- `GR-SEC-008` authorization enforced server-side

View File

@@ -24,7 +24,7 @@
"id": "QG-004",
"type": "fast",
"name": "Structural rg checks",
"command": "(rg 'new\\s+[^\\s(]+Factory\\(' lib/Service || true) | wc -l\n(rg --glob '!**/*Factory.php' 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' lib/Service || true) | wc -l\n(rg \"\\b(accessServicesFactory|directoryServicesFactory|userServicesFactory|authServicesFactory|tenantServicesFactory|settingServicesFactory|userRepositoryFactory|authRepositoryFactory|authGatewayFactory)\\(\" pages lib templates web || true) | wc -l\n(rg -n 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' pages -g '*.php' || true) | wc -l\n(rg -n '\\bDB::' pages -g '*.php' || true) | wc -l\n(rg -n 'app\\([^\\n]*Factory::class\\)->create' pages/admin -g '*.php' || true) | wc -l\n(rg -n 'Factory::class' pages/admin -g '*.php' || true) | wc -l\n(rg -n 'ApiResponse::readJsonBody\\(' pages/api/v1 -g '*.php' || true) | wc -l"
"command": "(rg 'new\\s+[^\\s(]+Factory\\(' core/Service || true) | wc -l\n(rg --glob '!**/*Factory.php' 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' core/Service || true) | wc -l\n(rg \"\\b(accessServicesFactory|directoryServicesFactory|userServicesFactory|authServicesFactory|tenantServicesFactory|settingServicesFactory|userRepositoryFactory|authRepositoryFactory|authGatewayFactory)\\(\" pages core templates web || true) | wc -l\n(rg -n 'new\\s+[^\\s(]+(Service|Gateway|Repository)\\(' pages -g '*.php' || true) | wc -l\n(rg -n '\\bDB::' pages -g '*.php' || true) | wc -l\n(rg -n 'app\\([^\\n]*Factory::class\\)->create' pages/admin -g '*.php' || true) | wc -l\n(rg -n 'Factory::class' pages/admin -g '*.php' || true) | wc -l\n(rg -n 'ApiResponse::readJsonBody\\(' pages/api/v1 -g '*.php' || true) | wc -l"
},
{
"id": "QG-005",

View File

@@ -2,8 +2,8 @@
## Schichtgrenzen
1. MUST SQL nur in `lib/Repository/**` halten.
2. MUST Business-Logik in `lib/Service/**` halten.
1. MUST SQL nur in `core/Repository/**` halten.
2. MUST Business-Logik in `core/Service/**` halten.
3. MUST `pages/**` auf Input, Auth/AuthZ, Orchestrierung, Response begrenzen.
4. MUST NOT Business- oder Permission-Logik in `templates/**` legen.
@@ -11,7 +11,7 @@
1. MUST in Actions/Helpern/Templates nur `app(Foo::class)` verwenden.
2. MUST NOT in `pages/**` direkt `new ...Service|Gateway|Repository` nutzen.
3. MUST NOT in `lib/Service/**` (ausser `*Factory.php`) direkt `new ...Factory|Service|Gateway|Repository` nutzen.
3. MUST NOT in `core/Service/**` (ausser `*Factory.php`) direkt `new ...Factory|Service|Gateway|Repository` nutzen.
4. MUST NOT in `pages/admin/**` `Factory::class` referenzieren oder `app(...Factory::class)->create...` nutzen.
## Input / Validation

View File

@@ -15,9 +15,9 @@ Policy-Hinweis:
## Struktur-Gates (schnell)
```bash
(rg 'new\s+[^\s(]+Factory\(' lib/Service || true) | wc -l
(rg --glob '!**/*Factory.php' 'new\s+[^\s(]+(Service|Gateway|Repository)\(' lib/Service || true) | wc -l
(rg "\b(accessServicesFactory|directoryServicesFactory|userServicesFactory|authServicesFactory|tenantServicesFactory|settingServicesFactory|userRepositoryFactory|authRepositoryFactory|authGatewayFactory)\(" pages lib templates web || true) | wc -l
(rg 'new\s+[^\s(]+Factory\(' core/Service || true) | wc -l
(rg --glob '!**/*Factory.php' 'new\s+[^\s(]+(Service|Gateway|Repository)\(' core/Service || true) | wc -l
(rg "\b(accessServicesFactory|directoryServicesFactory|userServicesFactory|authServicesFactory|tenantServicesFactory|settingServicesFactory|userRepositoryFactory|authRepositoryFactory|authGatewayFactory)\(" pages core templates web || true) | wc -l
(rg -n 'new\s+[^\s(]+(Service|Gateway|Repository)\(' pages -g '*.php' || true) | wc -l
(rg -n '\bDB::' pages -g '*.php' || true) | wc -l
(rg -n 'app\([^\n]*Factory::class\)->create' pages/admin -g '*.php' || true) | wc -l

View File

@@ -3,7 +3,7 @@
## Kernregeln
- Architektur- und Schichtgrenzen: `/docs/explanation-architektur.md`
- `lib/**`-Regeln und Instanziierung: `/docs/reference-lib-standards.md`
- `core/**`-Regeln und Instanziierung: `/docs/reference-core-standards.md`
- Kurzkonventionen: `/docs/reference-konventionen.md`
- Request/Input/Validation: `/docs/howto-request-input-validation.md`