Implements MeshVault M1 (issues #6–11): - Four-service Docker Compose stack (nginx, PHP-FPM 8.3, PostgreSQL 17, Node assets) - Slim 4 + PHP-DI routing with escaped PHP views and production/dev error handling - Immutable validated AppConfig with redacted diagnostics - JSON stdout Monolog logging with job-scoped context - Tailwind CSS v4 deterministic locked builds with template scanning - POSIX and PowerShell dev wrappers (up/down/test/lint/assets/watch) - Startup config validation fails before FPM serves as unprivileged www-data - migrate/seed explicitly unavailable until M2 (#12); #10 remains open Verified via clean-start acceptance on remote host (keith@192.168.2.23).
3.2 KiB
Contributing to MeshVault
Setup and checks
Host requirements: Docker Compose v2+ with Linux containers. No host PHP, Composer or Node is required.
# Start the stack (builds images if needed)
./dev.sh up
# Or on Windows: .\dev.ps1 up
# Run checks inside containers
./dev.sh test
./dev.sh lint
# Build assets deterministically
./dev.sh assets
# Watch during development
./dev.sh watch
If you have PHP 8.3+ and Composer 2 locally, you can also run:
composer install --no-interaction
composer validate --strict
composer lint
composer test
Commit both composer.lock and package-lock.json for reproducible builds.
migrate and seed are unavailable until M2 (#12); they exit nonzero and leave
#10 open. Never remove volumes with down -v; the wrapper forbids it.
composer lint enforces PSR-12 on PHP in src, public, config, bin,
templates, db/migrations and tests. composer test runs foundation checks
and PHPUnit unit/integration tests. Add behavior and regression tests with each
implementation.
Conventions
- PHP: PSR-12, four spaces, LF, UTF-8 without BOM, final newline, no closing PHP tag in PHP-only files. Use strict types in new PHP source files.
- Use
MeshVaultas the future application namespace; PascalCase classes and file names, camelCase methods/variables, UPPER_SNAKE_CASE constants. PSR-4 wiring is M1. - Database: plural snake_case tables, snake_case columns,
idprimary keys and singular_idforeign keys. Use UTC for stored application timestamps; distinguishadded_atfrom filemtime. Parameterize SQL and version schema changes. - Keep domain/services, persistence and HTTP rendering separate. Validate at boundaries, escape rendered values and protect state-changing requests against CSRF.
- Never infer file deletion from catalog removal. Restrict physical operations to configured managed roots; preserve source files, and test rollback/recovery paths.
- Do not introduce a framework, runtime dependency or storage behavior without documenting its choice in the relevant issue.
Workflow
- Choose an issue and check its dependencies; milestones group outcomes, not a strict schedule. In particular, repository service #28 precedes worker #25.
- Use branches such as
feature/20-import-scan,fix/47-missing-fileordocs/5-contributing. - Keep changes focused and include tests and documentation. Test failure paths for filesystem operations as well as the successful path.
- Use
type: concise imperative descriptioncommits, such asdocs: document managed-storage semanticsortest: cover hash mismatch. Types includefeat,fix,docs,test,refactor,buildandchore. Existing history used emoji-prefixed messages; new commits need no emoji. - Include issue references, commands/results, limitations and migration/storage effects in the review description. Do not close implementation issues before their acceptance criteria are verified and the work is committed/reviewable.
Never commit credentials, dependencies, generated assets, library contents or
PostgreSQL data. notes/ and .superpowers/ are local-only planning storage.
Contributions are under AGPL-3.0-only, the project license.