# DDR-0028: Python Code Quality & Maintainability Improvements (Post-Framing Stabilization)

## Status
Accepted

## Context

Following stabilization of the E27 framing, presentation, and session layers (with full test coverage passing, including deframer resynchronization and round-trip encryption tests), a structured code review was performed on the `elke27_lib` repository.

The review confirmed strong architectural discipline and protocol correctness, but identified several **Python-specific best practice improvements** related to maintainability, readability, and long-term evolvability.

These findings do **not** affect protocol semantics, cryptography, or message correctness and therefore do not warrant new ADRs. They represent implementation-quality decisions and belong in a Development Decision Record.

## Decision

We will perform a **non-behavioral refactoring pass** focused on Python best practices, guided by the following principles:

• No protocol changes  
• No wire-format changes  
• No behavior changes  
• All existing tests must remain valid  
• Changes must improve clarity, not abstraction depth  

## Decisions and Rationale

### 1. Standardize Import Ordering

**Decision**  
Adopt consistent import grouping across all modules:

1. Standard library  
2. Third-party dependencies  
3. Local project imports  

**Rationale**  
• Improves readability and consistency  
• Reduces merge friction  
• Aligns with PEP 8 and common tooling expectations  

---

### 2. Consolidate Magic Numbers into Constants

**Decision**  
Promote frequently used protocol and crypto literals into clearly named constants or constant containers.

**Scope**  
• Framing constants (STARTCHAR, escape rules)  
• Cryptographic block sizes  
• Fixed IVs already treated as constants  

**Rationale**  
• Makes protocol rules explicit  
• Prevents accidental divergence between modules  
• Improves test readability and intent  

**Non-Goal**  
• No new abstraction layers  
• No runtime configurability  

---

### 3. Improve Docstring Coverage for Public APIs

**Decision**  
Add or expand docstrings for public-facing functions and helpers where intent, constraints, or failure modes are not obvious.

**Rationale**  
• Supports maintainers and reviewers  
• Clarifies invariants and error behavior  
• Improves static analysis and documentation tooling  

**Explicitly Excluded**  
• Private helpers whose behavior is self-evident  
• Exhaustive protocol documentation already covered by ADRs  

---

### 4. Narrow Exception Handling Where Practical

**Decision**  
Replace overly broad exception catches with specific exception handling where the failure mode is known (e.g., JSON parsing, UTF-8 decoding).

**Rationale**  
• Improves debuggability  
• Preserves stack traces with meaningful context  
• Aligns with the existing error taxonomy (`E27Error`, `E27CryptoError`, etc.)  

**Non-Goal**  
• No change to error propagation semantics  
• No new error types without justification  

---

### 5. Reduce Function Size in Orchestration Code

**Decision**  
Refactor very large orchestration functions (e.g., smoketest entry points, connection flows) into smaller helpers with single responsibilities.

**Rationale**  
• Improves testability  
• Reduces cognitive load  
• Makes protocol phases explicit without changing behavior  

**Explicitly Excluded**  
• Core protocol encode/decode paths  
• Framing and encryption hot paths  

---

### 6. Logging Consistency

**Decision**  
Standardize logger creation across modules using a single pattern.

**Rationale**  
• Uniform logging behavior  
• Easier filtering and redirection  
• Avoids accidental logger shadowing  

---

### 7. Type Hint Consistency

**Decision**  
Use modern built-in generics (`dict[str, Any]`, `list[bytes]`, etc.) consistently across all modules.

**Rationale**  
• Project minimum Python version already supports this  
• Improves clarity and tooling support  

---

## Out of Scope

The following are **explicitly not addressed** by this DDR:

• Protocol changes (handled by ADRs)  
• Cryptographic algorithm changes  
• Wire format changes  
• Session or authentication semantics  
• Performance optimizations  
• Refactoring for abstraction purity  

---

## Consequences

### Positive
• Cleaner, more maintainable codebase  
• Easier onboarding for contributors  
• Lower long-term refactoring risk  
• Better alignment with Python tooling and linters  

### Neutral
• No behavior changes  
• No test changes required  
• No compatibility impact  

### Risks
• Low risk of cosmetic merge conflicts  
• Requires discipline to keep refactors non-functional  

---

## Validation

• All existing tests MUST pass unchanged  
• No new tests required for refactoring-only changes  
• CI serves as the regression guard  

---

## Related Decisions

• ADR-0100–0103 (Framing, schema-0 semantics, session lifecycle)  
• DDR-0027 (api_link unframed request / framed encrypted response)  
• DDR-0029 (Deframer resynchronization rules)  
