Skip to content

The flow

From an email arriving to the work item closing.

Page Covers
1. Capture n8n creates or joins the work item, then the brain assesses and decides
2. Execute n8n runs the branch for whichever action was chosen
3. Approve and loop The human decides, we reconcile, we send, and back to the brain
The work item, walked Every field across five different paths. A review artefact
Stages Counters and step tracing: how to tell where an item is, and what it cost

End to end

flowchart TB
    T["Email arrives"] --> L

    subgraph CAP ["1. Capture"]
        L["<b>1.1</b><br/>n8n stores raw in landing,<br/>joins or creates the work item"]
        L --> B["<b>1.2</b><br/>Brain: classify, resolve, decide"]
    end

    subgraph EX ["2. Execute"]
        S{"Switch on<br/>action.name"}
        S -->|"draft_reply"| D["<b>2.1</b><br/>Draft, then write<br/>the approval record"]
        S -->|"draft_holding_reply"| DH["<b>2.2</b><br/>Acknowledgement,<br/>then approval record"]
        S -->|"close_item"| C(["<b>2.3</b><br/>Stop"])
    end

    subgraph APP ["3. Approve"]
        Q["<b>3.1</b><br/>Item waits in<br/>the review app"]
        Q --> H{"<b>3.2</b><br/>Human decides"}
        H -->|"approve"| RC{"<b>3.3</b><br/>Reconcile: did they<br/>already reply themselves?"}
        RC -->|"yes"| CM(["closed_manual"])
        RC -->|"no"| SND["<b>3.4</b><br/>Send via the mail connector"]
    end

    B --> S
    D --> Q
    DH --> Q
    H -->|"discard"| C
    SND --> B2["<b>4. Loop</b><br/>Brain, with the outcome"]
    B2 --> S

    classDef llm fill:#7c3aed,stroke:#5b21b6,color:#ffffff
    class B,B2 llm

Purple means a model call

Throughout these docs, a purple node is where a language model is invoked: non-deterministic and billable. Everything else is code, a database query, or a rule, and behaves the same way every time.

The loop passes through the brain each time, so a conversation's cost is its brain_calls count. That is why max_brain_calls exists.

Everything reaches a human. There is no path where an AI-generated action is sent without approval. Some items arrive with a draft to approve, some arrive with nothing and the human writes it, and attention_reason says which and why.

Resolve and decide do not return to n8n. They are stages inside a single brain call, so n8n calls once and gets back an assessment plus an action. Drafting is a second call, deliberately, so a draft failure does not lose the classification already paid for.

Rows written elsewhere

Table Written at
message 1.1 inbound, and step 3 outbound after sending
decision Every brain call
stage_trace Every stage, as reached
approval Step 2, when a gated action is proposed
mask_map First time a value is masked, then reused for the item's life

The work item's state at each point is shown on that step's own page.

Where a problem goes

Three destinations, and conflating them is how a client ends up looking at our outages. The general rule is in architecture. For this product:

Goes to Client sees
escalated_by_design Client human, in the review app The item
escalated_cannot_determine Client human, in the review app The item
System failure Us, in the BOS Console Nothing. It retries

parse_failure is genuinely both. The email still needs answering by a human today, and the failure signals a regression we need telling about. So the item escalates to the client and an alert fires to us.

Surfaces

Term Is Audience
Client review app {tenant}.app.octopodia.com.au The client. Approvals and history
BOS Console console.octopodia.com.au Operators only

portal is reserved for the Internal Portal and is not used for either (ADR-0022 ยง4).