> For the complete documentation index, see [llms.txt](https://docs.eyepop.ai/developer-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eyepop.ai/developer-documentation/platform/pop/pop-forwarding.md).

# Forwarding

Chaining Pop components, and what each one receives

Forwarding is how a list of [components](/developer-documentation/platform/pop/pop-components.md) becomes a pipeline. A component's `forward` names what runs next and what those components receive — each detection as its own crop, the whole frame, or, after tracking, one selected frame per track.

### The forward object

| Field                                   | Type    | Description                                                                                                                            |
| --------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `targets`                               | list    | The components to run next.                                                                                                            |
| `operator.type`                         | string  | `crop`, `full`, `crop_with_full_fallback`, `select_crop`, or `select_full`.                                                            |
| `operator.includeClasses`               | list    | Restricts forwarding to these class labels.                                                                                            |
| `operator.crop.maxItems`                | integer | Caps how many detections are cropped per frame. Defaults to 16. Rejected on `select_crop`, which forwards one detection per selection. |
| `operator.crop.boxPadding`              | float   | Expands each crop box by this factor before cutting.                                                                                   |
| `operator.crop.orientationTargetAngle`  | float   | Rotates each crop to this angle in degrees — how skewed text is straightened before OCR.                                               |
| `operator.select`                       | object  | How a select operator picks its frame. Required on `select_crop` and `select_full`, rejected on every other operator.                  |
| `operator.select.mode`                  | string  | `most_relevant`, the only mode.                                                                                                        |
| `operator.select.relevancyModel`        | string  | Ability, by alias, that scores each tracked detection on every frame. A detection it finds nothing on is never selected.               |
| `operator.select.relevancyModelUuid`    | string  | The same, by uuid. Mutually exclusive with `relevancyModel`.                                                                           |
| `operator.select.minTrackLengthSeconds` | float   | Tracks shorter than this are never selected. Must not be negative.                                                                     |
| `operator.select.intervalSeconds`       | float   | Report a selection this often while a track lives, instead of once at its end. Must be positive.                                       |

The `select` attributes are explained in [Select Operators](/developer-documentation/platform/temporal-context/select-operators.md).

#### Operators

**`crop`** cuts each detection out of the frame and runs the targets on the cutouts. This is the workhorse: detect a vehicle, crop it, find the plate inside it.

**`full`** passes the whole frame through untouched. What it means depends on whether you also filter classes:

* `full` alone runs the targets on the frame as independent stages, unattached to the parent's detections.
* `full` **with** `includeClasses` runs the targets on the whole frame but attaches their results to the parent's matching detections. Use it when a model needs the full scene for context but its output belongs to a specific object.

**`crop_with_full_fallback`** crops when the parent detected something, and falls back to the full frame when it detected nothing — so a Pop still returns an answer for media where the first stage found no objects.

**`select_crop`** and **`select_full`** go on a `tracking` component's forward and run the targets once per track, on the frame that shows it best, instead of on every frame. Their results arrive late, as selected predictions. [Learn more](/developer-documentation/platform/temporal-context/select-operators.md).

#### Filtering by class

`includeClasses` narrows what gets forwarded to the labels you list. On `eyepop.vehicle:latest`, `includeClasses: ["car", "truck"]` sends cars and trucks downstream and leaves buses and motorcycles behind.

Naming a label the parent ability cannot produce is rejected when the Pop is compiled, so a typo fails at the boundary rather than silently forwarding nothing.

When the parent restricts itself with [`classes`](/developer-documentation/platform/pop/pop-components.md#restricting-to-classes), `includeClasses` may only name labels from that list. Any other label could never be forwarded, so it is rejected the same way.

### Composability

Any component can forward to any component. Apart from the select operators, which only a `tracking` component's forward can use, there is no type pairing the platform rejects, so the real constraints are about what makes sense:

| Component          | Sensible parents                    | Notes                                                                                                                                    |
| ------------------ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `inference`        | anything, or top level              | A `crop` forward from a detector is the common case.                                                                                     |
| `tracking`         | a detector, via `crop`              | Tracking needs objects to track and video to track them across. The only component whose forward can use `select_crop` or `select_full`. |
| `contour_finder`   | an inference producing segmentation | Nothing to contour without masks.                                                                                                        |
| `component_finder` | an inference producing segmentation | Nothing to split without masks.                                                                                                          |
| `forward`          | anything, or top level              | Used to branch.                                                                                                                          |

A finder scopes itself to the nearest enclosing inference component, following the chain up through any intervening finders. A finder placed at the top level, with no inference above it, scopes to everything on the frame.

Three rules the platform does enforce:

* A component `id`, if you set one, must be unique in the Pop.
* Every `inference` component must name exactly one ability, by alias or uuid.
* `select_crop` and `select_full` sit on a `tracking` component's forward and nowhere else.

### Next steps

* [Components](/developer-documentation/platform/pop/pop-components.md) — every component type and its attributes
* [Examples](/developer-documentation/platform/pop/pop-examples.md) — worked pipelines end to end
* [Select Operators](/developer-documentation/platform/temporal-context/select-operators.md) — running deep analysis once per tracked object
* [Pop Object](/developer-documentation/platform/pop/pop-object.md) — the shape of a Pop and how its top-level components run
