09 — Deliver Cloud Router effects with idempotent remote contracts
## Objective Recover engine-owned router meeting/case/queue effects without duplicate remote resources, hidden failure or callback feedback loops. ## Code and evidence app/services/kaukus_router/lifecycle.rb (Base#with_error_handling rescues Client::Error and returns nil); app/services/kaukus_router/lifecycle/{meeting,case}.rb; app/services/kaukus_router/client.rb; app/models/{meeting,case,speaker}.rb; app/controllers/api/cloud_router_callbacks_controller.rb; app/controllers/meetings_controller.rb; app/jobs/{start_case,end_meetings}_job.rb. Existing client creation APIs expose no idempotency parameter. Persisting stream_uuid after a remote create leaves an ambiguous-success window if the response/local write is lost. ## Changes - Verify paired API contracts and implement required server-side stable-key creation/replay/lookup support for meeting/case effects. Bind stable keys to event/effect and logical run/lifecycle, not transient jobs. Preserve explicit remote identity across retries. - Split independently failing create/start/stop and speaker-queue reconciliation into tracked effects with dependencies. End/cleanup must remain possible when earlier start is uncertain; prevent strict ordering from trapping teardown. - Add strict delivery-aware client/lifecycle behavior with bounded timeouts, response validation and sanitized failure classification. Do not let rescue-and-nil mark a delivery successful. Retain legacy callers' compatibility through shared interfaces, not copy-pasted clients. - Move engine-owned direct integration calls from controllers/jobs/Meeting/Case integration bundles to consumers. Callback-originated accepted commands must not echo remote lifecycle requests back to the router; preserve existing origin differences. - Preserve cloud_router_content_allowed? and meeting/case confidentiality. Do not publish private titles or speaker queues. Current-state queue replacement is idempotent; resource creation requires the receiver contract, not just local dedup. - Avoid stale starts after reset/new generation and reconcile outstanding remote IDs before superseding. Capture identifiers needed after local deletion. ## Acceptance and tests Extend spec/services/kaukus_router/lifecycle/{meeting,case,speaker}_spec.rb and spec/controllers/api/cloud_router_callbacks_controller_spec.rb; proposed outbox router consumer specs. Test remote success/local ack loss, duplicate keys returning same ID, bounded errors/timeouts, partial completion, callback loops, start/end race, missing resources, confidentiality and no external request on rollback. Require paired-service contract evidence, not only a mock accepting an invented header. Run bundle exec rspec spec/services/kaukus_router spec/controllers/api/cloud_router_callbacks_controller_spec.rb; RuboCop changed Ruby. ## Depends on https://task.matda.me/tasks/tsk_2qravp6n9b — effect/origin contract. https://task.matda.me/tasks/tsk_beu5nmfqfj — worker/ledger. https://task.matda.me/tasks/tsk_5fdrm4pptn — callback suppression/capture. Coordinate shared entrypoints with task 06 and Teams/restreamer tasks. ## Questions - Which router release/repository supplies stable-key creation/replay and recovery lookup? Existing Rails methods do not prove server support; verify with its contract before coding the adapter. - If that contract is missing, is coordinated server work authorized, or is an explicit blocked/operator-reconciliation exception approved? Keep strict duplicate-free acceptance unmet until resolved.
Checklist
0 of 0 completeNo checklist items.
- Area
- Kaukus
- Kind
- Feature
- Priority
- Medium
- Task ID
tsk_asp6xca5mq- Updated