Documentation Index

Fetch the complete documentation index at: https://docs.aifabrix.ai/llms.txt

Use this file to discover all available pages before exploring further.

CIP step catalog

Prev Next

Reference for $defs.cipStep* on Business Entity execution.cip.operations.*.steps. Each step is a single keyed object — one of the types below. Authoring context: Configure data flow. Certification: CIP execution.

CIP is not an integration system

CIP has no if / else / switch step. It does not hide vendor logic or replace Connected System capabilities. Pipelines compose fetch, map, filter, and related steps over declared operations — vendor behavior stays in OpenAPI, MCP, and certified capabilities, not inside CIP control-flow.

Prerequisites

  • Configure data flow open while editing execution.cip
  • Schema synced via Builder validate (or local aifabrix validate <systemKey>)

Where it lives

Layer Location
Steps <datasourceKey>.jsonexecution.cip.operations.<key>.steps[]
Schema defs External datasource schema $defs.cipStep*
Help Builder topic cipOverview, schemaCatalog

How to set

  1. Open the operation under execution.cip.operations that matches your capability key.
  2. Append steps as single-key objects only — never invent keys outside this catalog.
  3. Prefer the common list pattern: fetchpaginatemapfilteroutput.
  4. Re-run aifabrix validate <systemKey> after each structural change.

Defaults and examples

Step Purpose Typical default
fetch Obtain raw payload source: openapi + openapiRef
paginate Walk list pages strategy: cursor (when vendor pages)
map Normalize fields useFieldMappings: true
merge Combine accumulates strategy: array
filter ABAC / JMESPath abac.mode: mandatory
output Emit records mode: records
pythonInline Sandboxed transform rare — prefer map/filter

Step types at a glance

Step Purpose
fetch Obtain raw payload from OpenAPI, HTTP, another datasource, a viewpoint, or local record storage
paginate Walk cursor / page / offset results after fetch
map Normalize vendor fields via fieldMappings or inline DSL
merge Combine accumulated fetch outputs
filter ABAC and/or JMESPath filter before emit
output Emit records for sync and agents
pythonInline Sandboxed transform when declarative steps are not enough

Common optional step wrappers: enabled, order, stepId, onError, lineage (where schema allows).

fetch

Purpose: Load a payload for the operation. source is where I/O happens. CIP operation shape (create | update | delete) is persist vs read on local storage — not the capability key. Pipeline output.mode stays records (plural collection envelope).

Required: object key fetch with source. Closed enum:

source Meaning Required Forbidden
openapi Vendor/OpenAPI HTTP openapiRef and/or operationId SQL query
http Explicit method + path method + path SQL query
datasource Nested datasource operation datasource (unless composition selects) + operation (default list) SQL query
viewpoint Saved SQL against record storage (storageType: view) SQL string query vendor path/method; persist shapes
record Local table I/O (no vendor HTTP) none beyond source (identity/body from the capability and exposed.profiles) SQL query; do not treat as vendor HTTP

source: record is singular. Do not write fetch.source: records. output.mode: records remains plural.

CIP fetch.source compiles to COM source (same pattern as writeShape). Named perspectives are source: viewpoint. Local table and vendor fetches are the other tokens — capability keys such as list / search / get are examples, not a closed set.

Useful optional fields (vendor/nested): query (parameter object), bodyTemplate, headers, expectedItemsPath, accumulate, skipUnauthorized, parameters (datasource). query is a SQL string only for viewpoint.

{
  "fetch": {
    "source": "openapi",
    "openapiRef": "list",
    "query": { "limit": "100" }
  }
}

Viewpoint (SQL against governed record storage):

{
  "fetch": {
    "source": "viewpoint",
    "query": "SELECT customer_id AS \"customerId\", SUM(amount) AS total FROM records_example_orders GROUP BY customer_id"
  }
}

Local table read (list, get, or any other published read capability — no shape):

{
  "fetch": {
    "source": "record"
  }
}

Local table persistshape on the operation, not inferred from the key:

{
  "registerEmployee": {
    "shape": "create",
    "steps": [
      { "fetch": { "source": "record" } },
      { "output": { "mode": "records" } }
    ]
  }
}

When to use: Vendor or child-entity HTTP (openapi / http / datasource); calculated read-only perspectives (viewpoint); local record-storage list/get/create/update with no vendor HTTP (record).
When not: Do not invent a sixth source. record is not vendor HTTP. viewpoint is not a table write. Do not use a capability key (create, list, …) as the fetch source.

paginate

Purpose: Continue fetching pages after an initial fetch (typically list).

Required: paginate.strategycursor | page | offset | none.

{
  "paginate": {
    "strategy": "cursor",
    "cursorField": "$.paging.next.after",
    "cursorParam": "after",
    "pageSizeParam": "limit",
    "pageSize": 100,
    "maxPages": 50
  }
}

When to use: List operations with vendor pagination.
When not: Single-record get / create / update / delete unless the vendor truly pages those responses.

map

Purpose: Transform raw API records into the normalized metadata model.

Required: object key map (inner properties optional; defaults apply).

Prefer useFieldMappings: true so fieldMappings.attributes drive expressions. Optional inputPath (default $.items[*]) and inline overrides.

{
  "map": {
    "useFieldMappings": true,
    "inputPath": "$.results[*]"
  }
}

When to use: Almost every list/get after fetch.
When not: Do not invent a transform step — use map (or pythonInline as last resort).

merge

Purpose: Merge accumulated fetch outputs (fetch.accumulate: true) — data transformation only.

Required: merge.strategyobject | array | union | byKey (optional keyField).

{
  "merge": {
    "strategy": "array"
  }
}

When to use: Multi-fetch orchestration into one batch.
When not: Simple single-fetch pipelines — skip merge.

filter

Purpose: Filter mapped records before output (ABAC and/or JMESPath).

Required: object key filter.

{
  "filter": {
    "abac": {
      "mode": "mandatory",
      "policyScope": "datasource"
    }
  }
}

abac.mode: mandatory | optional | disabled. Optional expression (+ expressionLanguage: jmespath).

When to use: Enforce or explain ABAC on list/get results.
When not: Do not disable ABAC in production tenants without a documented exception.

output

Purpose: Finalize the pipeline and emit records.

Required: object key output. Prefer mode: records.

{
  "output": {
    "mode": "records"
  }
}

Optional: limit, includeConfidence.

When to use: End of every operation that should return governed records.
When not: Leaving output off often breaks sync and agent consumption — include it unless validate proves otherwise.

pythonInline

Purpose: Sandboxed inline Python on the current record batch when declarative steps cannot express the transform.

Required: pythonInline.code — small pure snippet; no imports, IO, or network (runtime must enforce sandboxing).

{
  "pythonInline": {
    "code": "return [r for r in records if r.get('status') == 'active']"
  }
}

When to use: Rare edge transforms after map.
When not: Prefer map / filter first. Prefer execution.engine: python only for full custom handlers, not routine field mapping.

Validate

aifabrix validate <systemKey>

Reject invented step keys; use this catalog and Builder help topic schemaCatalog when property names fail.

Common mistakes

Mistake Fix
transform or other invented keys Use map / filter / pythonInline
fetch without openapiRef for source: openapi Add openapiRef matching openapi.operations
List without output Add {"output":{"mode":"records"}}
pythonInline for routine field renames Use map + fieldMappings