Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0057
ADR-0057: PEP 649/749 annotation convention — Any + named comment, never TYPE_CHECKING-only names in evaluable annotations
| field | value |
|---|---|
| Status | Accepted — Accepted (executed under Mohamed's direction) |
| Date | 2026-09-21 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0057-pep649-annotation-convention.md — permalink at 8ceb2e5a4 (unchanged on master since that commit) |
| Wiki register entry | ADR-0057 (wiki status: Accepted) |
The record
Date: 2026-09-21 · Status: Accepted (executed under Mohamed's direction)
Context
Under Python 3.14's lazy annotation evaluation (PEP 649/749), a name
imported only under if TYPE_CHECKING: raises NameError whenever
inspect.signature resolves the annotation at runtime. The regenerated
tests/generated_* pins surfaced three live instances:
agents/volk_registry.py::__init__—audit: AuditLogger | None(kernel.audit.logger, L4: a runtime import would be an upward edge)orchestrator/prolog_worker.py::query_explained×2 —-> ProofResult(core.prolog_adapter: importing it loads janus/libswipl at import time — a side effect deliberately deferred tostart())
Decision
When a type cannot be imported at runtime — either because the import would
violate the layer model, or because the import carries an unacceptable
side-effect cost — the annotation is written as Any and the real type is
named in an adjacent comment with the reason. A TYPE_CHECKING-only import
referenced from an evaluable annotation is a defect (it is a NameError
waiting for the first introspector).
This is the convention both files already used for other L4 payloads
(redis_state: Any | None = None, # RedisStateManager); the ADR makes it
uniform and gives the reason.
Consequences
- The three instances are fixed; the regenerated generated-tests pins pass.
- The layer model loses nothing: the annotation never named the type at runtime anyway; the comment preserves the documentation value.
- The static ratchet (ADR-0056) counts TYPE_CHECKING edges, so removing these also pays down static debt (87 → 86 for the prolog_worker one).
Related ADRs
- Also mentioned: ADR-0056
Rulings cited
None.
Specs cited
None (or no spec page exists for the ones named).