Problem
The gateway is pull-only — providers are polled and the merged view is rebuilt on a cadence. A diagnostic client expects live push: ros2_medkit exposes a trigger subsystem and an SSE stream at GET /api/v1/triggers/events. A drop-in client typically creates a trigger, then listens, so the subscription path must exist or the client receives nothing.
Proposal
Add the v1 slice of triggers + SSE to the gateway:
- A refresh-and-diff loop on the off-path tokio runtime: re-poll/merge on the cadence, diff successive
MergedViews, and emit change events health_changed, fault_raised, fault_cleared.
POST /api/v1/triggers + GET /api/v1/triggers (+ GET/DELETE /triggers/{id}): basic subscription with a minimal filter (by entity and/or severity). Rich condition predicates are explicitly deferred.
GET /api/v1/triggers/events: an SSE stream delivering events matching the caller's triggers, framed per the captured contract (diff against the contract/golden SSE sample).
Acceptance
Blocked by
Problem
The gateway is pull-only — providers are polled and the merged view is rebuilt on a cadence. A diagnostic client expects live push: ros2_medkit exposes a trigger subsystem and an SSE stream at
GET /api/v1/triggers/events. A drop-in client typically creates a trigger, then listens, so the subscription path must exist or the client receives nothing.Proposal
Add the v1 slice of triggers + SSE to the gateway:
MergedViews, and emit change eventshealth_changed,fault_raised,fault_cleared.POST /api/v1/triggers+GET /api/v1/triggers(+GET/DELETE /triggers/{id}): basic subscription with a minimal filter (by entity and/or severity). Rich condition predicates are explicitly deferred.GET /api/v1/triggers/events: an SSE stream delivering events matching the caller's triggers, framed per the captured contract (diff against thecontract/goldenSSE sample).Acceptance
POST /triggersregisters a basic entity/severity subscription andGET /triggerslists it;DELETE /triggers/{id}removes it.GET /triggers/eventsstreams SSE frames; an integration test that raises and clears a fault (via a provider) observesfault_raisedthenfault_clearedframes matching the contract shape.health_changed.REQ_0900/TEST_0900linked.Blocked by