WithService is now a simple factory call — no reflect, no auto-registration.
New() calls discoverHandlers() after all opts run, scanning Config for
service instances that implement HandleIPCEvents.
This eliminates both double-registration and empty-placeholder issues:
- Factories wire their own lifecycle via c.Service()
- HandleIPCEvents discovered once, after all services are registered
- No tension between factory-registered and auto-discovered paths
Co-Authored-By: Virgil <virgil@lethean.io>
- HandleIPCEvents only auto-registered for services the factory didn't
register itself (prevents double handler registration)
- Auto-discovery only creates Service{} placeholder when factory didn't
call c.Service() — factories that register themselves keep full lifecycle
Addresses Codex review findings 1 and 2 from third pass.
Co-Authored-By: Virgil <virgil@lethean.io>
- WithOptions copies the Options slice (constructor isolation regression)
- WithService auto-discovers service name from package path via reflect
- WithService auto-registers HandleIPCEvents if present (v0.3.3 parity)
- Add test for failing option short-circuit in New()
Co-Authored-By: Virgil <virgil@lethean.io>