> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# The branch-decision contract: from CDP to flows

> One contract for answering the cross-subgroup question — when a CDP segment, score, event sentence, or chart should drive a Flows branch — covering the CDP events / render / engagement side alongside the flows / runs / follow-ups side, both flagship pages, the build-your-first-branch contract, and the return path that keeps an audit row straight.

# The branch-decision contract: from CDP to flows

Two sibling subgroups sit next to each other in the Concepts tree: **CDP
& Intelligence** and **AI & Automation**. A reader landing on either
subgroup's **read this first** page still had the same question
unanswered: when the capture side says something happened, what is the
next thing the action side runs on that fact? The answer was never two
separate pages — it is one contract.

A **branch decision** is the pivot where a flow executes one path rather
than the alternative: a `condition` node picks a handle (`yes` or `no`,
an intent name, a sentiment bucket, an A/B variant) and the run enters
the routed arm. CDP captures the raw fact (the event, the segment, the
rendered chart); Flows executes the branch on that fact. This page
aggregates the event-narrative (the CDP side of the story) with the
build-branch contract (the automation side) into one carrier.

## What the two subgroups actually cover

The two subgroups divide the question cleanly, and whichever one you
landed on tells you which half you owe:

* **CDP & Intelligence covers the capture side** — CDP
  [events](/concepts/cdp-event-model), rendered output (accounts,
  identity, segments, scoring, conversations, analytics), and
  engagement. Capture output is a **fact** — an event sentence,
  segment membership, a score — a flow branch can read.
* **AI & Automation covers the action side** —
  [flows](/concepts/flow-execution-model), runs (executions), and
  follow-ups. Execution output is a **next branch** and a recorded
  step trace — not a new CDP fact.

The capture side says "something happened"; the action side runs the
next branch on that fact. The whole point of the contract is keeping
the two halves in one system of record instead of discovering, at
invoice time, that the segment read one truth and the flow acted on
another.

## The two flagship pages, one paragraph each

* **CDP & Intelligence's flagship** is the [Analytics
  pipeline](/concepts/analytics-pipeline): a conversation is captured
  as raw events, the rollup groupings turn those into statistics, and
  the inference layer turns statistics into the chart a customer reads.
  Conversation → statistics → inference, in one pipeline, on the same
  append-only event stream the
  [CDP event model](/concepts/cdp-event-model) defines; nothing in the
  subgroup writes over the raw record.
* **AI & Automation's flagship** is the [Flow execution
  model](/concepts/flow-execution-model): a flow definition becomes a
  run through the trigger catalog and node semantics, and the executor
  advances the run node by node through handles until the webhook
  hand-off or a terminal state closes it. Flow → execution → webhook
  hand-off, one run over one published version.

Each page is its subgroup's entry point on its own; a reader who landed
here from either flagship now has the third piece — the contract that
holds them together.

## The build-your-first-branch contract

The branch you are tempted to insert — a CDP segment read into a flow's
condition — is covered by one template:

```http theme={null}
POST /api/v1/flows/:id/execute
```

```json theme={null}
{
  "execution_id": "exec_branch01",
  "condition_input": "segment.repeat_buyers = true",
  "selected_handle": "yes",
  "audit_row_id": "audit_branch01",
  "status": "completed"
}
```

Three caveats, each guarding one way the loop can quietly muddle the
audit row:

1. **The \~30-minute no-ACK window is on the record.** A branch on a
   `sent` leg still inside the carrier no-DLR grace window (for SMPP
   channels; Grace: 30 minutes, per the [DLR model: two
   planes](/concepts/dlr-model-two-planes) timer contract) flips on a
   pending fact, not a final fact. The audit row says the segment
   criterion evaluated at the time the window opened; the branch never
   claims the stuck leg "delivered" — the most common reason an
   aggregated read gets muddled.
2. **The page you chose owns the branch.** Once you land on either
   subgroup's flagship as your gateway, the aggregated page is the
   carrier that absorbs the flip — your subgroup is the sender of the
   fact, not the reader of it. A reader who starts by asking "who owns
   this branch?" avoids the most damaging inversion: a flow branch and
   a CDP rule each claiming to decide.
3. **Suspended at the point the \~2-minute run-timer slips.** An
   execution parked past the per-resume budget (300 s per the
   [flow-execution model](/concepts/flow-execution-model)) finalizes as
   `timeout` — a `failed: timeout` verdict, not `completed`, and not an
   in-flight run that somehow "caught up." A branch that follows a
   timed-out run without treating the verdict as a hard failure is the
   second way an aggregated read lies.

### Worked chain: the `repeat-buyer` segment into a flow branch

```http theme={null}
POST /api/v1/flows/:id/execute
```

1. **CDP leg.** The segment read sits on the [CDP event
   model](/concepts/cdp-event-model) ingest envelope as input; the
   read resolves `true` against the tenant-owned gate, so the criterion
   is a fact rather than a projected state.
2. **Condition → branch.** The flow run walks the published version
   (the [flow-execution model](/concepts/flow-execution-model)), the
   condition node evaluates the criterion, and the `yes` handle wins;
   the per-resume 300 s budget applies from this hop onward.
3. **Aggregate.** The aggregated visit flips the audit row back to
   `completed` on the comparison visit — a completed verdict is a
   completed verdict, and the group-by-kind chart reads the same row
   the branch already wrote.

### One timeline: no-DLR promotion through the aggregate visit

```json theme={null}
{
  "execution_id": "exec_branch02",
  "dlr_anchor": "pending",
  "audit_row_id": "audit_branch02",
  "status": "completed_with_errors",
  "error": "dlr_resolved_after_branch"
}
```

When the DLR surface never replies, the chain is a partial promotion —
the audit row still reads "audit row was not ambiguous," the aggregated
visit parses the receipt leg as "not announced as a truth value," and
the branch rejects any promotion across charts. The promotion is
never a default event name; it is the exception your counter-invoice
catches.

### The no-ACK-no-fallback section

The upstream fallback branch reads the raw segment input (the criterion
minted by the CDP ingest envelope) without a new branch emit:

* **The unconfigured fallback branch.** When the raw input says the
  segment criterion is absent, the chain rejects the flip and the
  audit row preserves the slate it was given — the fallback is the
  exception that says "we are not going to assume no-ACK means a
  maybe."

Let each subgroup publish its own render, then tie the route to the
aggregate inversion; there is no fifth branch to invent.

## The return path

The return path is the same pair of a read surface that reads the raw
mandate and the audit row:

* **The raw mandate is the raw segment input** — the criterion minted
  by the CDP ingest envelope says "same segment, input digest, no
  failure" without a new emit contract.
* **The aggregate read is the external read of the audit row** — the
  group-by-kind visit resolves the flip with no lingering branch,
  because there is no cross-subgroup exchange in it.

Once the pair absorbs both caveats the branch is on record; a branch
across charts never muddles the invoice.

## Related

* [CDP event model](/concepts/cdp-event-model) — the append-only event
  stream the branch query ran on.
* [Analytics pipeline](/concepts/analytics-pipeline) — the
  conversation → statistics → inference chain the aggregate read rides.
* [Flow execution model](/concepts/flow-execution-model) — the run
  carving the branch and routing it through handles.
* [DLR model: two planes](/concepts/dlr-model-two-planes) — the
  timer contract the no-ACK caveat protects.
