fix(events): add unsubscribe() to EventBus protocol and implementations #11135

Closed
freemo wants to merge 4 commits from fix/events-eventbus-unsubscribe into master

4 Commits

Author SHA1 Message Date
controller-ci-rerun 6e2f6cd1d4 chore: re-trigger CI [controller]
CI / lint (pull_request) Successful in 39s
CI / quality (pull_request) Successful in 58s
CI / push-validation (pull_request) Successful in 26s
CI / build (pull_request) Successful in 42s
CI / typecheck (pull_request) Successful in 1m25s
CI / security (pull_request) Successful in 1m23s
CI / helm (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 6m30s
CI / docker (pull_request) Successful in 1m44s
CI / integration_tests (pull_request) Successful in 10m38s
CI / coverage (pull_request) Successful in 11m28s
CI / status-check (pull_request) Successful in 3s
2026-06-13 16:08:53 -04:00
HAL9000 1cf41ec6e2 fix(events): wire test mocks + steps for EventBus.unsubscribe
CI / lint (pull_request) Successful in 40s
CI / typecheck (pull_request) Successful in 1m10s
CI / quality (pull_request) Successful in 49s
CI / build (pull_request) Successful in 58s
CI / helm (pull_request) Successful in 59s
CI / push-validation (pull_request) Successful in 26s
CI / unit_tests (pull_request) Successful in 6m15s
CI / integration_tests (pull_request) Successful in 10m19s
CI / security (pull_request) Failing after 12m42s
CI / coverage (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / status-check (pull_request) Has been cancelled
The 2026-05-12 reviewer flagged blockers in the unsubscribe test scaffolding
and CI now reproduces them as ruff format mismatches plus six errored BDD
scenarios:

- features/event_bus.feature:213 "Multiple handlers — unsubscribe removes
  only the target" referenced an undefined "I unsubscribe the first handler"
  step, and step_remaining_handlers_received iterated over every collector
  including the one just unsubscribed (BLOCKER 4).
- features/fix_then_revalidate_coverage_boost.feature:{191,201,212,329} and
  fix_then_revalidate_coverage_r3.feature:49 errored because the _MockEventBus
  and _FailingEventBus stubs in the step files satisfied the old EventBus
  Protocol (emit + subscribe) but not the new unsubscribe member, and
  FixThenRevalidateOrchestrator's runtime isinstance(event_bus, EventBus)
  check (the EventBus Protocol is @runtime_checkable) rejected them as
  invalid.
- features/steps/event_bus_steps.py and infrastructure/events/logging_bus.py
  needed `ruff format` cleanup; both were one-line whitespace adjustments.

Fixes applied:

1. Add unsubscribe() no-op to the three mock EventBus classes so the runtime
   protocol check accepts them.
2. Add an explicit "I unsubscribe the first handler" step that records which
   collector index was removed, plus track last_subscribed_type from the
   multi-subscribe steps so the unsubscribe step can locate the event_type.
3. Update step_remaining_handlers_received to skip the recorded index when
   verifying remaining-handler counts.
4. Apply ruff format to the two files CI flagged.

Local gates: lint PASS, unit_tests on all three affected feature files PASS
(88 scenarios, 349 steps, 0 errors).
2026-06-13 15:50:20 -04:00
controller-ci-rerun 76360c0e30 chore: re-trigger CI [controller] 2026-06-13 15:50:20 -04:00
freemo df5912df8f fix(events): add unsubscribe() to EventBus protocol and implementations
Add the missing unsubscribe() method to the EventBus Protocol in
protocol.py and both concrete implementations (ReactiveEventBus,
LoggingEventBus). Unsubscribed handlers are no longer called on
subsequent emit() calls, breaking the reference cycle that prevented
garbage collection of owning objects in long-running processes.

Includes comprehensive BDD regression tests covering unsubscription
for both implementations, no-op behavior for non-registered handlers,
multi-handler targeting, and Protocol stub coverage.

ISSUES CLOSED: #10356

---
Automated by CleverAgents Bot
Supervisor: Implementation | Agent: task-implementor
2026-06-13 15:50:20 -04:00