# DDR-0006: Framing API Uses framer() and deframer() Functions

Status: Accepted  
Date: 2025-12-22  
Related ADRs: ADR-0005 (protocol-specific connection pumps)

## Context

E27 link-layer processing (START 0x7E, escape rules, LENGTH, CRC, resync) must be
unit-testable and usable from a TCP stream reader. There was a choice between a
stateful class-based interface and a functional interface.

## Decision

E27 link-layer framing will be implemented as functions in framing.py:

- framer(protocol, data_frame) -> bytes
- deframer(state, chunk) -> (new_state, results)

The deframer state is explicit and passed in/out (no hidden globals).

## Rationale

- Pure functional interface is easy to unit-test and fuzz
- Explicit state avoids hidden coupling and makes stream parsing deterministic
- Keeps connection.py focused on I/O and lifecycle, not protocol rules
- Simplifies reuse across sync/async transports or emulators

## Consequences

- connection.py must maintain a deframer state object per connection
- deframer must be able to return multiple frames per chunk and continue after errors
- framing.py must not perform socket I/O, JSON parsing, or encryption
