Problem
Several services receive a shared Symfony\Component\Finder\Finder instance from dependency injection and then mutate it with calls such as files(), directories(), in(), name(), and depth(). Finder is a mutable iterator builder, so reusing the injected instance can leak criteria between consumers or between repeated command executions in the same process.
Current Behavior
The DI container exposes Finder::class as an injectable service. Commands and synchronizers mutate that instance directly while discovering command classes, resources, Git hooks, or packaged skills.
Expected Behavior
Every operation that needs Finder configuration MUST receive a fresh Finder instance before applying criteria. Consumers SHOULD depend on a small factory abstraction so tests can still mock Finder creation without sharing mutable state.
Failure Surface
Affected code includes Finder consumers in src/Console/Command, src/Console/CommandLoader, and src/Agent/Skills, plus their tests. The bug is most visible when multiple Finder-backed operations execute in one long-lived Composer process.
Proposal
Introduce a FinderFactory abstraction that creates new Finder instances and inject that factory into Finder consumers instead of injecting Finder directly. Keep tests focused by mocking the factory and configuring the returned Finder mock.
Implementation Strategy
- Add a
FinderFactoryInterface and default FinderFactory implementation.
- Register the factory in
DevToolsServiceProvider.
- Replace direct
Finder injection in current consumers with the factory.
- Request a fresh Finder for each scan before applying criteria.
- Update tests to assert factory usage and prevent accidental shared Finder mutation.
Non-goals
- Replacing Symfony Finder with another traversal implementation.
- Changing which files, directories, commands, hooks, or skills are discovered.
- Broadly refactoring command execution or service registration beyond Finder creation.
Acceptance Criteria
Functional Criteria
Regression Criteria
Architectural / Isolation Criteria
Problem
Several services receive a shared
Symfony\Component\Finder\Finderinstance from dependency injection and then mutate it with calls such asfiles(),directories(),in(),name(), anddepth(). Finder is a mutable iterator builder, so reusing the injected instance can leak criteria between consumers or between repeated command executions in the same process.Current Behavior
The DI container exposes
Finder::classas an injectable service. Commands and synchronizers mutate that instance directly while discovering command classes, resources, Git hooks, or packaged skills.Expected Behavior
Every operation that needs Finder configuration MUST receive a fresh Finder instance before applying criteria. Consumers SHOULD depend on a small factory abstraction so tests can still mock Finder creation without sharing mutable state.
Failure Surface
Affected code includes Finder consumers in
src/Console/Command,src/Console/CommandLoader, andsrc/Agent/Skills, plus their tests. The bug is most visible when multiple Finder-backed operations execute in one long-lived Composer process.Proposal
Introduce a
FinderFactoryabstraction that creates new Finder instances and inject that factory into Finder consumers instead of injecting Finder directly. Keep tests focused by mocking the factory and configuring the returned Finder mock.Implementation Strategy
FinderFactoryInterfaceand defaultFinderFactoryimplementation.DevToolsServiceProvider.Finderinjection in current consumers with the factory.Non-goals
Acceptance Criteria
Functional Criteria
Finderservice directly into consumers.Regression Criteria
Architectural / Isolation Criteria