# DDR-0009: Handler Contract for E27 Message Domain Commands

Status: Accepted  
Date: 2025-12-22  
Related ADRs: ADR-0007 (E27 Layering), ADR-0012 (Inventory-Driven API Surface)

## Context

E27 contains many commands across many domains. Without a consistent handler contract,
implementations drift and the dispatcher becomes complex. A uniform signature and
return type ensures handlers remain composable and testable.

## Decision

All E27 message handlers follow a uniform contract:

- Signature:
  handle_<command>(cmd_payload: dict, ctx: MessageContext) -> list[dict]

- cmd_payload is the value of the command key within the domain object.
- ctx provides correlation/diagnostics context (e.g., json_seq, connection id, timestamps).

- Return:
  A list of event dictionaries. Minimum required keys for each event:
    - "type": "<domain>.<command>" (or more specific event types if implemented)
    - "data": normalized/validated data (may initially mirror cmd_payload)
    - optional: "note", "warnings", "meta"

- Errors:
  Handlers raise ValueError (or a library-defined decode exception) with a clear English
  error message. The dispatcher catches and converts to an error DispatchResult.

## Rationale

- Keeps dispatcher logic simple and stable
- Enables unit testing handlers without dispatcher or network
- Supports later evolution from dict events to typed dataclasses without changing dispatch flow

## Consequences

- All domain modules must conform to this handler signature
- Dispatcher must wrap handler output into a standardized DispatchResult
- Validation failures must not crash the reader loop; they surface as structured errors
