Skip to content

Flow Typing Contract for Retriever

Purpose

This page defines the current flow typing contract for Retriever runtime code, plugins, and shared examples.

Use this page for: - Flow[...] signature forms, - composite input/output routing semantics, - lifecycle ordering across stepper, multiprocessing, and dora.

Related guides: - docs/guides/spatial_types_v1.md - docs/guides/data_eventstream_v1.md - docs/guides/type_composition_v1.md

Supported Signature Forms

All of these are valid:

  • Flow[(A, B), C]
  • Flow[tuple[A, B], C]
  • Flow[A, (C, D)]
  • Flow[(A, B), (C, D)]

(A, B) and tuple[A, B] are normalized to the same internal contract.

Core Rules

  1. Generic element types must be flow-I/O compatible.
  2. Composite tuple generics cannot mix None with concrete types.
  3. Unqualified field access is allowed only when unique across a composite view.
  4. Ambiguous unqualified read, write, and has access must raise.
  5. Qualified access is always valid for collisions.

For new runtime code, define envelopes with @io:

from retriever.flow import Flow, io


@io
class Observation:
    value: float


@io
class Command:
    action: float


class Controller(Flow[Observation, Command]):
    def step(self, input: Observation) -> Command:
        return Command(action=input.value * 0.1)

@io is the public decorator for Flow I/O types. Use it directly, without @dataclass.

Examples: - inp.value - inp.A.value - inp._get_signal("B.value") - inp._set_signal("A.value", v)

Collision and Aliasing

When class names collide in a composite signature, aliases are deterministic by declaration order:

  • Name__1
  • Name__2

Qualified routing and published ports use these aliases.

Lifecycle Contract

Runtime initialization order is:

  1. instantiate from IR init config
  2. call __lazy_init__() if present
  3. call reset()

This applies across: - in-process stepper, - multiprocessing backend, - dora backend.

Validator Policy

Default validator mode: - allows tuple-literal and tuple-output signatures, - enforces local I/O compatibility and tuple/None constraints.

Strict mode (--strict-single-io): - rejects composite tuple input/output signatures, - enforces single-envelope contracts for teams that require them.

Adjacent Layers

The flow typing contract is not the same thing as the domain typing layers:

  • retriever.types.spatial
  • robotics boundary dataclasses and validation helpers
  • retriever.types.data
  • event/data/export contracts for collection, replay, and dataset manifests

Use the flow typing contract to describe how flows compose. Use retriever.types.spatial and retriever.types.data to describe what those payloads mean.