All Decisions

ADR-0011: Extensibility Strategy for Processing Lenses

DateFebruary 8, 2026
CategoryDomain Logic
Tags
processing-flowfeature-flags

Context

  • Future features may want to apply different "processing lenses" (e.g., meeting extraction, contact capture, receipts parsing) that transform or enrich InboxItem during processing.
  • We need a design that allows incremental addition of lenses without destabilizing the core processing pipeline.

Decision

We will design processing as a small, pluggable pipeline with a first-class ProcessingLens interface and a registry of lenses. Lenses may be enabled/disabled and versioned.

Core principles:

  • Minimal core: the default processing UI and taxonomy (see ADR-0008) remain authoritative.
  • Lenses operate as optional, deterministic transforms that can:
    • Suggest a ProcessedType and metadata (tags, category, context)
    • Populate actionDetails (e.g., parsed date for Defer)
    • Provide validation warnings or auto-suggestions
  • Lenses must be pure (no side effects) and return a typed result; any persistence must be done by the central processing orchestrator.
  • Lens metadata (id, version, description, enabled) will be stored so processed items can record which lens (if any) influenced them.

Scope boundaries:

  • This ADR defines the high-level strategy and constraints for lenses. Specific lens implementations (e.g., receipts parser) will be separate ADRs or design documents.

Rationale

  • Pluggability allows evolving functionality without changing the processing core.
  • Versioning lenses protects against behavior changes affecting historical processed items; storing lens id/version with the ProcessedItem improves reproducibility.
  • Pure lenses simplify testing and reasoning.

Consequences

  • Positive:

    • Easy to add specialized processors later (ML-based or heuristic) behind feature flags.
    • Clear separation of concerns: UI/orchestration vs transformation logic.
  • Downsides:

    • Additional coordination when lenses should be chained (need deterministic ordering).
    • Slight implementation overhead for registry, versioning, and lens contracts.

Implementation notes

  • Define a ProcessingLens interface in the codebase with a stable input/output contract and a light-weight result object.
  • Store lensId and lensVersion (nullable) on ProcessedItem when a lens materially affects the result.
  • Start with a single default/no-op lens and add a registry that can be extended behind feature flags.