Skip to content

Latest commit

 

History

History
91 lines (70 loc) · 3.87 KB

File metadata and controls

91 lines (70 loc) · 3.87 KB

AGENTS.md

Instructions for AI agents working on this project.

Fundamental rule: never run PHP/Composer on the host machine

Everything goes through the builder container, via Castor:

castor builder -- bin/console cache:clear    # one-off command
castor builder -- bin/console make:migration # one-off command

Host prerequisites only: Docker, Bash, Castor.

Essential commands

castor start                                 # build + install + up + migrate
castor stop                                  # stop the stack
castor logs [--service=service]              # logs (frontend, postgres, ...)
castor app:install                           # composer install + importmap:install + qa:install
castor app:db:migrate                        # Doctrine migrations (alias: castor migrate)
castor app:db:fixtures                       # fixtures (alias: castor fixtures)
castor app:cache-clear                       # clears var/cache (alias: castor cache-clear)
castor postgres                              # opens a psql shell (alias: castor pg)
castor pg -- "SELECT now();"                 # one-shot psql query (or raw psql args: castor pg -- -c "\dt")

Docker / workers:

castor docker:build [--service=service]
castor docker:up [--service=service]
castor start-workers                         # start workers (worker profile, currently unused — see Stack)
castor stop-workers

Castor contexts

The context changes how tasks are executed (APP_ENV, compose files, etc.):

castor --context=test qa:phpunit             # APP_ENV=test, for tests
castor --context=ci ...                      # like test, tuned for CI
castor --context=prod ...                    # production images on a dedicated local stack (docker-compose.prod.yml)

Always run tests and anything touching the database with --context=test. Without option, the default context applies.

Stack

  • Symfony at the repo root (docroot = public/)
  • PostgreSQL 16: user/pass/db = qotd/qotd/qotd
  • nginx + php-fpm (service frontend), Traefik router, HTTPS on <root_domain> (see castor.php)
  • cron service for scheduled tasks (e.g. posting the daily quote)
  • Symfony AssetMapper for JS/CSS (importmap.php) — no Node/yarn build step
  • A Messenger worker service is defined in infrastructure/docker/docker-compose.yml but currently commented out (no async transport in use yet)
  • Production ships as two images (php and nginx), built from the "Production stages" of infrastructure/docker/services/php/Dockerfile and pushed by .github/workflows/build-push.yml. php-fpm and nginx configuration (services/php/php/, services/php/nginx/) is shared with the dev frontend container. The production cron job runs bin/console qotd:run with the php image (the cron service is dev only)

QA — before considering a task done

Tools run inside the builder.

castor qa                                    # everything: cs + phpstan + twig-cs + phpunit
castor qa:cs [--dry-run]                     # PHP-CS-Fixer (.php-cs-fixer.php)
castor qa:phpstan [-b]                       # PHPStan level 8 (phpstan.neon)
castor qa:twig-cs                            # Twig-CS-Fixer
castor qa:phpunit                            # PHPUnit

After any PHP/Twig code change: castor qa:cs --dry-run, castor qa:phpstan, then castor qa:phpunit.

Conventions

  1. Never invoke docker compose by hand: use the docker_compose() / docker_compose_run() functions from .castor/docker.php to write new tasks.
  2. Never hardcode ports or project names: git worktree support automatically isolates project/volumes/ports (castor docker:ports). Use variable('project_name') etc.
  3. New recurring task? Make it a Castor task (castor.php or .castor/*.php), not a shell script.
  4. QA tool dependencies live in tools/<tool>/composer.json (not in the root composer.json).