# Automation and orchestration

> The half of a process nobody should be doing by hand - what starts it, what it reaches, and why a scenario that takes three days survives a restart on the second

Source: https://aipril.dev/docs/processes/automation

## What runs between the moves

A process holds the state a person cares about: whose turn it is, what has been approved, what is
still open. Automation is everything that happens between those moves - fetch this, write that,
wait for a reply, notify, retry, and do the next thing.

A scenario that takes three days is ordinary here, and ordinary means it has to survive everything
that happens in three days, including the service restarting.

## What sets something off

| Trigger | Fires when |
|---|---|
| A task is created | Something was filed - notify, enrich it, check it against another system |
| A task changes status | The decision has been made, and now the consequences run |
| A row in a spreadsheet changes | Somebody edited the plan, the price list, the register |
| A schedule | Every night, every Monday, the first of the month - with the timezone as part of the definition and not an assumption |
| A webhook | Something outside the platform happened, and it can say so |

The webhook path is signed and quota-limited, and its token can be rotated - so "let a partner
system start our process" does not mean leaving a door open indefinitely.

## What a scenario can do

The steps are the ones you would expect to need, and no more: call a service, call a **connector**,
**ask a person** and wait for their answer, wait for a period, branch on a condition, set a value,
loop over a list, repeat until something is true, run branches in parallel, and **try something with
a compensation if it fails**.

That last pair is what distinguishes a workflow engine from a script. If step four fails after steps
one to three have already changed things in the outside world, the compensation is what undoes them
- in order and deliberately, instead of leaving a half-finished state for somebody to find.

The **human step** is the other one worth naming. A scenario can stop, ask a person, and wait -
for an hour or for a week - without holding anything open, and continue from exactly where it
stopped when the answer arrives.

## Nodes: the vocabulary of "do something"

A scenario is assembled from **nodes**, and a node is one capability of one system, made safe by
somebody else so the author does not have to write an integration.

The built-in set covers what the platform touches: send to **Telegram** or **Slack**; send and
receive **email**; call any **HTTP service**; read and write the platform's own things - datasets,
the [data engine](https://aipril.dev/docs/engine.md), dashboards, [spreadsheets](https://aipril.dev/docs/spreadsheets.md), the ledger,
references, the knowledge base, documents, applications; and call an **agent**.

### And you can add your own

The palette is not a fixed list. A tenant administrator installs a **node package** - a manifest in
an archive - and its nodes appear in the palette grouped under it, usable exactly like a built-in
one. No deployment, no restart, no ticket to us.

The design decision underneath is unusual and deliberate: a node package is **purely declarative**. It describes an outbound HTTP call, or an inbound webhook, as
data - and a single trusted runtime executes that description. **No third-party code ever runs
inside the platform.** A package cannot contain code, which means installing one is not a decision
about whether to trust somebody's code.

For logic that cannot be expressed that way, the answer is the ordinary one: host it wherever you
like - your own backend, a serverless function, an automation tool you already run - and point a
declarative node at it. The same pattern as the HTTP node in any of the tools people compare this
to, with the difference that the rest of your nodes are not that.

Practically:

- Installing runs a **dry run first**, showing what the package would add - its nodes, its webhooks,
  the licence features it needs - before anything is installed.
- **Re-installing upgrades**, and webhook tokens for hooks that still exist are preserved, so
  whoever was calling you does not have to be reconfigured.
- A package that needs a secret declares a **credential type**; the secret is stored encrypted and
  chosen by connection in the node, not typed into the scenario.

## What a real one looks like

Scenarios stop being small the moment they meet an actual sales process. This one starts when a
deal moves to "proposal sent", and it lives in Telegram because that is where the sellers are:

```mermaid
flowchart TD
    T["Deal moves to<br/>'proposal sent'"] --> A["Load the deal<br/>and its contact"]
    A --> AG["AI Agent: summarise the deal<br/>and draft the follow-up"]
    AG --> B{"Deal value?"}
    B -->|"under the threshold"| C["Telegram to the owner:<br/>the draft, and three buttons"]
    B -->|"at or over it"| D["Telegram to the owner<br/>and the sales lead"]
    C --> W["Wait for an answer"]
    D --> W
    W -->|"Won"| E["Move the deal to Won,<br/>notify the channel"]
    W -->|"Needs a discount"| F["Raise a discount<br/>approval task"]
    W -->|"Lost"| G["Ask for the reason,<br/>write it onto the deal"]
    W -->|"nothing in two days"| H["Remind once,<br/>then escalate"]
    H --> W
    F --> I{"Approved?"}
    I -->|"yes"| E
    I -->|"no"| G
    G --> Z["Close, and add it<br/>to the loss report"]
```

Nothing in it is exotic - and that is the point. It branches on a value, talks to two different
audiences, waits for a human answer that arrives from a messenger, raises a task in a
[process](https://aipril.dev/docs/processes/what-you-can-do.md) when a decision is needed, chases when nobody replies,
and ends in data somebody will report on. A scenario is allowed to be as involved as the work is.

The agent step is worth pointing at. It is a node like the others - it reads the deal, writes a
summary and drafts what to send next - and what it produced does not go anywhere on its own: it
arrives in the seller's Telegram as the message they are about to approve. The assistant does the
typing; the person still decides. That shape - **agent proposes, human confirms** - is the ordinary
one here, not a safety feature bolted on afterwards.

## The editor, and who actually drives it

There is a canvas: nodes on a board, edges between them, a palette to search, an inspector for the
node you selected, properties for the scenario as a whole, and a run view that shows an actual
execution step by step - what fired, what it returned, where it is waiting.

**The canvas is for reading and adjusting, not for building from nothing.** Building is a
conversation: describe the scenario and
it is assembled - the branches, the waits, the retry, the escalation nobody remembers to add. Then
you open the canvas to see what you got, change the threshold, rename a step, insert the extra
notification.

That is the opposite of how these tools normally work, where the canvas is the product and the
assistant is a feature bolted onto it. The diagram above is a perfectly reasonable thing to draw by
hand. It is a much better thing to describe in four sentences and then correct.

## Automation inside a transition

The two engines meet at one place worth understanding, because it is where most real automation
lives.

A transition in a process can be bound to a scenario. When somebody moves the task, the task
**holds in place** while the scenario runs - visibly "processing", not silently pending. What the
scenario produces is written back into the task's fields, and then:

- on success, the transition completes and the task moves where it was going;
- on failure, it either reverts to where it was, or routes to an error status the process defines.

There is a timeout, and a sweeper that finalises anything that outlived it - so a scenario that
never returns cannot leave a task stuck in "processing" forever. The completion is idempotent: an
answer that arrives twice is applied once.

## What is guaranteed

- **A run survives a restart.** Workflow state is persisted, never held in memory. The database row
  is the source of truth about when something should fire; the fast path is an optimisation, and a
  reconciler is the backstop that catches whatever it missed.
- **A timer fires once.** Not zero times because a process restarted, and not twice because two
  workers both noticed.
- **Fan-out is bounded, and the bound is checked when the process is compiled** - not discovered at
  three in the morning when a list turned out to have nine thousand entries.
- **A failed branch fails the parent.** A parallel section does not half-succeed quietly.
- **Payloads are encrypted and have a retention** - a workflow that carried personal data through it
  does not keep it forever by default.

## Next

[AI in processes](https://aipril.dev/docs/processes/ai.md) - describing a process in words, and the agent as a step
inside a scenario.
