Use Map / Transform (rollout.map) to reshape a list without a Code step. Choose a source list, then add ordered operations. Expressions use the workflow expression language with item and zero-based index in scope; extra wired inputs are available under inputs.

Operations

Operation What it does
Set fields Builds a new object or patches each item with fixed or expression values
Filter / Sort Keeps matching items or orders them by an expression
Distinct Keeps the first item for each evaluated key
Limit / Offset Takes the first n items or skips the first n items
Group Emits stable {key, items, count} rows, with an optional custom items field and metrics
Expand Evaluates a list per item and emits one parent row per element under the chosen field
Aggregate Computes count, sum, min, max, mean, collect, join, first, or last metrics
Select / Discard Keeps or removes named object fields
Join Matches a wired list by scalar or composite keys
Match rules Applies runtime-authored conditions and field expressions to each item

Operations run from top to bottom. Disabled operations stay in the pipeline but do not change the list. Distinct and group keep the order in which keys first appear. In-VM work is capped at 10,000 rows per operation: Expand and Join reject oversized operands and fail before allocating a larger result, while runtime Match rules use the same bound for potential rule evaluations.

Joining lists

Join keys can be one expression, such as item.customer_id, or a JSON array of expressions, such as ["item.workspace_id", "item.customer_id"]. A key containing null does not match.

  • Left keeps every left item and writes null for an unmatched join.
  • Inner keeps only matched items.
  • Anti keeps only unmatched left items and does not add the join field.
  • Semi keeps matched left items once and does not add the join field.
  • First match uses the first right item for a key. All matches emits one row for every pair.

The with expression must evaluate to a list; a wrong-shaped dynamic value fails the step instead of being treated as an empty list. When the left input item is a scalar, joined output keeps it under row and places the matched item under the configured join field.

Aggregate rows

Aggregate normally leaves the working list unchanged and publishes each metric as a named output. Choose Rows to replace the working list instead. With a group expression, each output row contains the group key and its metrics; if the key expression returns an object, its fields are merged into the row. A metric name that collides with one of those group-key fields fails the step instead of silently replacing the key. Without a group expression, Aggregate emits one metric row.

Rules as data

Match rules are read from an expression such as inputs.rules. It must return a list shaped like:

JSON
[
  {
    "when": "item.score >= 80",
    "set": {
      "grade": "\"pass\"",
      "review.priority": "item.score >= 95"
    }
  }
]

The when value and every value in set are expression strings. Rollout compiles them once for the operation and fails the step if any expression is invalid. First match stops after the first matching rule; All matches applies matching rules in order.