01 — Define outbox effect contracts and command routing
## Objective Produce the implementation contract for every existing voting-engine command and effect. Source scope: https://task.matda.me/tasks/tsk_zdaraph9uw. All paths below are relative to /home/mathias/work/moeteadm; evidence baseline 3c6524f1a. ## Existing code and findings app/services/voting_engine/{application,application_input,input,command_envelope,command_processor,transitions,case_lifecycle,meeting_lifecycle,bias_poll_lifecycle}.rb. CommandProcessor atomically records one voting_engine.changed event per accepted receipt. Payload is the transition result; bias/deletion context and request-only delivery inputs are incomplete. Vote commands can share run sequence, so sequence is not a deduplication key. ## Deliverables - Define proposed Outbox::EffectPlan and validated DeliveryContext contracts. Preserve event_type and existing result keys; add versioned metadata rather than breaking current readers. - Enumerate ApplicationInput/Input command types: poll lifecycle/unanimous decisions, five vote commands, participant/presence changes, case lifecycle/preparation, meeting start/end/reset, bias register/withdraw/delete, and low-level engine commands. Every type has explicit effects or an explicit no-external-effect classification. Unknown versions/types must block visibly, not silently succeed. - Stable delivery identity is event ID + effect key (+ stable recipient ID for per-recipient notifications). Define ordered lanes and nested effect consolidation; do not redispatch commands or manufacture receipts. - Capture required IDs/context before destruction; keep minimal immutable context, not HTML/session data. Include request notification suppression and initiating user where needed. Teams secrets belong in protected storage, not ordinary receipt/outbox JSON. - Preserve UI/system/cloud-router origin differences; callbacks must not echo remote start/stop commands. Low-level initialize_run must not accidentally start streaming integrations. - Define context collision handling: normalized context digest participates when present, without exposing secrets; preserve old digests for absent context. - Document at-least-once transport versus duplicate-free logical effect. Successful Action Cable publication is not browser acknowledgement; reconnect/refetch reconstructs current state. - Create an effect coverage table reused by producer, consumer and acceptance tests. Coordinate future command types with https://task.matda.me/tasks/tsk_zxbg4uyua2 rather than implementing outcome/no-seat features here. ## Acceptance and tests Proposed spec/services/voting_engine/outbox/effect_plan_spec.rb checks every command type is classified, deterministic effect keys, nested deduplication, malformed/unsupported context, deletion context and no-op cases. Extend command_envelope_spec.rb/application_spec.rb for digest compatibility and replay. Run bundle exec rspec spec/services/voting_engine/command_envelope_spec.rb spec/services/voting_engine/application_spec.rb spec/services/voting_engine/outbox/effect_plan_spec.rb; RuboCop changed Ruby files. ## Depends on None. Local contract work can proceed while provider questions are resolved; external guarantees remain release gates. ## Questions - Source acceptance currently requires duplicate-free external effects. Is that strict guarantee required for every integration and proposal email, or will an explicitly documented operator-reconciliation exception be approved? Do not assume an exception; provider-specific questions belong in the Teams/router/restreamer/mail tasks. - No unresolved local voting/UI scope question: cover existing engine-owned effects, not unrelated application notifications.
Checklist
0 of 0 completeNo checklist items.
- Area
- Kaukus
- Kind
- Research
- Priority
- Medium
- Task ID
tsk_2qravp6n9b- Updated