agentsclimarketplace

Symfony workflow

Skill event4u-app/agent-config/src/skills/symfony-workflow

Writes Symfony PHP — DI container, bundles, Doctrine, Messenger, Security voters, console commands. For Laravel / Eloquent / Artisan use `laravel`. For framework-free PHP use `php-coder`.From its SKILL.md

Install
npx -y skills add event4u-app/agent-config --skill symfony-workflow

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.5 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it

symfony-workflow

When to use

Use this skill for all Symfony-specific code generation and editing tasks, especially when working with:

  • Controllers (annotated / attribute-routed)
  • Request listeners / event subscribers
  • Services and Dependency Injection (services.yaml)
  • Forms and validators
  • Doctrine entities, repositories, and migrations
  • Security: firewalls, voters, authenticators
  • Messenger handlers and transports
  • Console commands
  • Bundles, compiler passes, and tagged services
  • Twig templates and view logic

This skill extends the base php-coder skill and applies Symfony conventions on top of the project's general PHP rules.

When to use the analysis sibling

When the task is understanding how a Symfony app boots, wires its container, routes requests, or fails at runtime — defer to project-analysis-symfony first, then return here for the edit. This skill assumes the kernel/container layout is already known.

Procedure: write Symfony code

First apply the php-coder skill for general PHP rules.

Then add these Symfony-specific checks:

  1. Confirm Symfonybin/console exists, composer.json lists symfony/framework-bundle.
  2. Confirm versioncomposer.lock for the framework-bundle major. 5.x → 6.x → 7.x differs in attribute routing, voter signatures, and Messenger DSN shape.
  3. Inspect app structure — standard, modular (src/Module/<Name>/), or DDD-style. Do not enforce a layout the project does not use.
  4. Check config layoutconfig/packages/<env>/, services.yaml autowiring vs explicit bindings, config/bundles.php.
  5. Check test conventions — PHPUnit/Codeception; unit vs integration vs functional split.

Core Symfony principles

  • Follow Symfony conventions unless the project explicitly does otherwise.
  • Keep controllers thin — delegate to services.
  • Rely on autowiring + autoconfigure unless the project has explicit bindings.
  • Prefer attributes over annotations on 6.x+; keep annotations only if the codebase still uses them.
  • Use service IDs by FQCN — App\Service\Foo, not custom string IDs.
  • Services are private by default; do not flip public: true to make tests pass.
  • Do not bypass the container with new on classes that have collaborators.

HTTP layer rules

  • Controllers:
    • extend AbstractController only when the project does
    • accept Request or a DTO; delegate business logic; return a Response variant
  • Use #[Route] attributes on 6.x+; YAML routes only where the project already does.
  • Use #[MapRequestPayload] / #[MapQueryString] (7.x+) for request DTOs when the project uses them.
  • Validate via Symfony Validator on the DTO, not inline in the controller.
  • Use ParamConverter / argument resolvers for entities only when the project uses them.

Validation rules

  • Symfony Validator with constraints on DTOs / entities.
  • Prefer attribute constraints (#[Assert\NotBlank], #[Assert\Email]) on 6.x+.
  • Render errors from ConstraintViolationListInterface — never compose error arrays by hand.
  • Validation is declarative; do not put domain validation in entity setters.

Service layer and DI rules

  • One responsibility per service; constructor injection.
  • Interfaces when there are multiple implementations or the boundary is mocked.
  • Tagged services for collecting implementations — #[AutoconfigureTag] or YAML tags, never an injected array of FQCNs.
  • Decorators via #[AsDecorator] (6.1+); respect priority.
  • Compiler passes only when wiring cannot be expressed via attributes/YAML.
  • Do not call Container::get in application code.

Routing rules

  • Follow the existing organization — attributes on controllers, or YAML in config/routes/.
  • Route names: <resource>_<action> (user_show, invoice_list).
  • #[IsGranted], #[RateLimit] at the route level, not inside the controller body.
  • requirements: for path parameter constraints; do not validate in the controller.

Response rules

  • Match the project's response style: Twig, JsonResponse, API Platform, or redirects with flash.
  • For APIs: consistent status codes; ConstraintViolationListapplication/problem+json; DTOs / serializer groups, not raw entities.
  • Do not return entities directly unless the project consistently does that.

Messenger and async work

  • Messenger for async/deferred work; one message class per intent.
  • Handlers: MessageHandlerInterface (5.x) or #[AsMessageHandler] (6.x+).
  • Route via framework.messenger.routing in config/packages/messenger.yaml.
  • Configure failure_transport explicitly — without it, failed messages disappear.
  • Pass IDs, not entities; the consumer re-fetches.

Events and subscribers

  • #[AsEventListener] (6.1+) or EventSubscriberInterface — match the project's convention.
  • Past-tense event names (UserRegistered, OrderPaid); one side-effect per subscriber.
  • Respect priority on kernel.request / kernel.response — wrong priority is a frequent bug source.

Security, voters, authorization

  • One firewall per surface in config/packages/security.yaml (main, API, admin).
  • Voters for object-level permissions; never role checks in templates or controllers.
  • #[IsGranted] on actions; $this->isGranted() only when the result drives downstream logic.
  • Stateless APIs: token-based authenticator, not form-login.

Config and environment

  • Read via ParameterBagInterface or #[Autowire(param: ...)] — never $_ENV directly.
  • New env vars in .env (+ .env.test); production values in deployment config.
  • Bundle config under config/packages/<bundle>.yaml; env overrides under config/packages/<env>/.

Doctrine and persistence

  • Doctrine ORM unless the project uses DBAL/raw SQL by convention.
  • Repositories for non-trivial queries; no inline QueryBuilder in controllers/services.
  • N+1 awareness: fetch joins via addSelect or EAGER when always needed.
  • Transactions via EntityManager::wrapInTransaction() for multi-write atomicity.
  • Lifecycle hooks (PreFlush, PostUpdate) — no domain logic there unless the project already does.

Migrations

  • Generate via doctrine:migrations:diff; review before commit.
  • Reversible — implement up() and down().
  • One concern per migration; destructive prod changes split into expand → migrate → contract.

Twig

  • Templates are dumb — presentation only; pre-computed view models from the controller/service.
  • Reuse via {% extends %} / {% include %} / macros.
  • Auto-escape on; |raw only when content is provably safe.

Bundles and compiler passes

  • Bundles are for reusable, redistributable code — not "another folder".
  • Compiler passes only when wiring cannot be expressed via attributes/YAML.

Console commands

  • #[AsCommand] (6.x+); one command class per intent; constructor injection.
  • Long-running: --limit, --time-limit, graceful SIGTERM shutdown.
  • Output via OutputInterface — never echo.

Output format

  1. Symfony code following framework conventions and project architecture.
  2. All related files (controller, service, DTO, repository, test, config) as needed.
  3. Schema changes — migration file plus updated entity/mapping.

Do NOT

  • Business logic in controllers, entities, listeners, or Twig.
  • Bypass the container with new on classes with collaborators.
  • $_ENV / $_SERVER direct access — go through the parameter bag.
  • Return Doctrine entities from an API endpoint — use DTOs or serializer groups.
  • Silently swallow Messenger failures — route to a failure transport.
  • Flip services public: true to make tests pass — use the test container.
  • Pass entities through Messenger — pass IDs.
  • Mix attribute and YAML routing for the same controller surface.

Gotcha

  • Autowiring fails silently when two implementations exist without explicit binding — read the error, don't just flip public: true.
  • #[IsGranted] is a no-op if the controller is not a service (autoconfigure handles it by default).
  • Messenger failure_transport is opt-in; without it, failures vanish.
  • Compiled container changes need cache:clear in prod before debugging "config not applied".
  • Symfony 7.x removed deprecated APIs — verify composer.lock before assuming 6.x patterns work.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most automation workflows skills give in ~1.9k tokens

Counted across 745 of the 1,008 authors here whose files we hold, read 2026-08-07

  • Write conventional commit messagesin 36 of 745, across 35 files
  • Delete branches after mergein 30 of 745, across 21 files
  • Make atomic commitsin 25 of 745, across 15 files
  • Write minimal code to pass testsin 22 of 745, across 10 files
  • Re-snapshot after navigation or DOM changesin 21 of 745, across 13 files
  • Use try-catch for error handlingin 20 of 745, across 8 files
  • Run tests before committingin 20 of 745, across 12 files
  • Write tests before implementationin 20 of 745, across 8 files
  • Configure branch protection rulesin 19 of 745, across 5 files
  • Explain the why in commit messagesin 19 of 745, across 9 files
  • Refactor code while tests remain greenin 19 of 745, across 6 files
  • Interact with elements using refsin 19 of 745, across 11 files

Said here and by no other author read

  • confirm the Symfony major version before coding
  • keep controllers thin and delegate to services
  • use constructor injection for dependencies
  • generate migrations using doctrine:migrations:diff
  • implement both up and down methods in migrations
  • configure an explicit messenger failure transport

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,750. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.