Symfony Migration Guide¶
This guide is for Symfony applications that already use scattered InstructorPHP glue and want to move onto the supported packages/symfony bundle surface.
The main migration goal is simple:
- keep domain logic in the source packages
- move Symfony-specific registration, config, and framework defaults under
cognesy/instructor-symfony
When You Should Migrate¶
You are a migration candidate if your app currently does any of the following:
- registers its own
Cognesy\Events\Dispatchers\SymfonyEventDispatcherbridge or event-bus parent wiring - enables
Cognesy\Logging\Integrations\Symfony\InstructorLoggingBundle - keeps framework-specific logging, telemetry, or Messenger wiring in
services.yaml - wires native-agent persistence or delivery helpers directly in app code
- mixes
packages/events,packages/logging, and app-local container glue to reproduce a framework package manually
What Moves, What Stays¶
Moves under packages/symfony:
- bundle registration
- the public
instructorconfig root - Symfony-aware HTTP transport defaults
- framework event mirroring
- package-owned delivery defaults
- telemetry exporter wiring and lifecycle cleanup
- logging presets and bundle-facing compiler-pass wiring
Stays in source packages:
- reusable event primitives in
packages/events - reusable logging primitives in
packages/logging - runtime logic in
packages/instructor,packages/polyglot,packages/agents, andpackages/agent-ctrl
The migration is about ownership, not duplication. You should end up with less app-local Symfony glue, not more wrappers around the same low-level classes.
Step 1. Install And Register The Bundle¶
Then enable the bundle:
If you still have the legacy logging bundle registered, remove it from config/bundles.php.
Step 2. Consolidate Config Under instructor¶
The supported config root is now:
Move Symfony-related app config under these subtrees as needed:
connectionsembeddingsextractionhttpeventsagent_ctrlsessionstelemetryloggingdelivery
Do not keep a second Symfony-specific root for logging or event delivery once the new bundle is in place.
Step 3. Replace Manual Event-Bus Bridging¶
Before:
- app code constructs or registers
SymfonyEventDispatcher - app code decides how
CanHandleEventsis parented or mirrored
After:
- let
packages/symfonyownCanHandleEvents - configure bridge behavior through:
Important boundary:
packages/eventsstill owns the reusableSymfonyEventDispatcherprimitivepackages/symfonyowns when and how that primitive is registered in a Symfony application
So keep packages/events for reusable code, but stop wiring the bridge manually in application service definitions unless you are deliberately replacing the package default.
Step 4. Migrate Logging¶
Before:
<?php
return [
Cognesy\Logging\Integrations\Symfony\InstructorLoggingBundle::class => ['all' => true],
];
After:
Migration notes:
- move from
instructor_loggingtoinstructor.logging - rename the old
defaultpreset todevelopment - keep custom
include_events,exclude_events, andtemplatesvalues; the new path still forwards those into the reusable logging pipeline - the legacy logging bundle should be treated as a compatibility shim, not the long-term public surface
Step 5. Move Telemetry Wiring Into The Package¶
If your app currently builds exporter services, projectors, or lifecycle listeners by hand, move that config under:
The package now owns:
- exporter selection
- projector composition
- runtime bridge wiring
- HTTP, console, and Messenger cleanup hooks
Application code should still own:
- credentials and endpoint values
- any domain-specific post-processing or alerting after export
Step 6. Use Package Delivery Seams Instead Of Ad Hoc Messaging¶
If your app currently forwards runtime events or execution handoff through custom Messenger messages, move toward the package-owned seams:
ExecuteAgentCtrlPromptMessageExecuteNativeAgentPromptMessageRuntimeObservationMessage
Configure the observation bridge explicitly:
instructor:
delivery:
messenger:
enabled: true
bus_service: message_bus
observe_events:
- Cognesy\Agents\Events\AgentExecutionCompleted
This makes the ownership split clear:
- execution and observation handoff live under
packages/symfony - low-level runtime events still come from the source packages
- your application still decides which forwarded events deserve queue fan-out
Step 7. Replace App-Local Session Defaults Only Where Needed¶
If your app currently chooses native-agent persistence through local service definitions, start with the package-owned config instead:
Only replace Cognesy\Agents\Session\Contracts\CanStoreSessions directly if you truly need a custom backend.
Rollout Checklist¶
- install
cognesy/instructor-symfony - enable
InstructorSymfonyBundle - consolidate config under
instructor - remove legacy logging bundle registration
- stop manually wiring the event bridge unless intentionally overriding package defaults
- move telemetry and delivery config into
instructor.telemetryandinstructor.delivery - run your package or app test suite with both HTTP and Messenger contexts covered
Current Compatibility Notes¶
The migration path is already supported for:
- event-bus ownership under
CanHandleEvents - telemetry exporter and lifecycle wiring
- logging preset and bundle-root migration
- AgentCtrl runtime and Messenger handoff surfaces
- native-agent session store selection
Still evolving:
- split-package publication bootstrap and Packagist registration for
cognesy/instructor-symfony - broader docs-site discoverability outside the package folder
Those rollout items do not change the runtime ownership model described above.