<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="eli.ai" agent="eli.ai diagram exporter" version="1">
  <diagram id="approval-and-resume-005b4004" name="Approval and resume">
    <mxGraphModel dx="1600" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1600" pageHeight="1200" math="0" shadow="0">
      <root>
        <mxCell id="0"/>
        <object id="1" label="Approval and resume" schemaVersion="1" diagramId="approval-and-resume-005b4004" canonicalAppearanceKey="md:docs/architecture/end-to-end-lifecycles.md#9" sourceSha256="005b40042b0841d222b96aee0feec3a152d5b35acd322ca64ff255594be20d31" metadataPayloadSha256="3e5de30f2065615bf4c6f3ec649138881dcfb1cd55ef8b5b65178a7c3ab472f3" generationKey="3bc4816c819c5e59eea2ce67ca62bf7806e399afed414d2c21840cd053f89c41" concepts="[&quot;End to end lifecycles&quot;,&quot;Approval and resume&quot;]" keywords="[&quot;pg-boss agent-resume&quot;,&quot;reattach SSE / inbox shows pending&quot;,&quot;agent loop&quot;,&quot;approval route&quot;,&quot;continuation worker&quot;,&quot;tool requires approval&quot;,&quot;allow or deny + note&quot;,&quot;IO execute pending call&quot;,&quot;native/MCP&quot;,&quot;require agents:execute / live user capability&quot;,&quot;idempotent AgentResumeJob&quot;,&quot;{workspaceId, runId, approvalId}&quot;,&quot;TX claim queued to running + load decided&quot;,&quot;record structured tool denial&quot;,&quot;continue model loop from cursor&quot;,&quot;terminal output or another suspension&quot;,&quot;Postgres&quot;,&quot;approval/cursor&quot;,&quot;Reviewer&quot;,&quot;tool&quot;,&quot;TX approval step + approval row + resume_cursor + suspended&quot;,&quot;result&quot;,&quot;TX decision + actor + step + run queued&quot;]" application="{&quot;name&quot;:&quot;eli-ai&quot;,&quot;version&quot;:&quot;0.1.0&quot;}" packages="{&quot;mermaid&quot;:&quot;11.16.0&quot;,&quot;mermaidCli&quot;:&quot;11.16.0&quot;,&quot;playwright&quot;:&quot;1.62.1&quot;,&quot;playwrightCore&quot;:&quot;1.62.1&quot;,&quot;puppeteer&quot;:&quot;25.6.0&quot;,&quot;puppeteerCore&quot;:&quot;25.6.0&quot;}" environment="{&quot;architecture&quot;:&quot;x64&quot;,&quot;containerImage&quot;:&quot;playwright:v1.62.1-noble@sha256:c091b21d9fae78c76e85cd4356431e9b018402f172a214fc7d7a5e9a7e29d8ac+node:26.3.1-bookworm-slim@sha256:209558c3e5e40e8adff68959d3c2ba7cd73723e716d89196878a0c362fa1e109&quot;,&quot;node&quot;:&quot;v26.3.1&quot;,&quot;platform&quot;:&quot;linux&quot;,&quot;yarn&quot;:&quot;4.17.1&quot;}" renderer="{&quot;browser&quot;:{&quot;executableSha256&quot;:&quot;0b20b130e7edd9dd51873be867761295fe0cfad490c2b9a64f95bd3cfc08fa71&quot;,&quot;name&quot;:&quot;chromium&quot;,&quot;revision&quot;:&quot;1234&quot;,&quot;version&quot;:&quot;151.0.7922.34&quot;},&quot;font&quot;:{&quot;family&quot;:&quot;Eli Diagram Inter Variable&quot;,&quot;fileSha256&quot;:&quot;3100e775e8616cd2611beecfa23a4263d7037586789b43f035236a2e6fbd4c62&quot;,&quot;licenseSha256&quot;:&quot;3b0a5fca3d17942cde889069889dedbbbd075e9b599968c82a95f4d944e9b345&quot;},&quot;mermaidConfigSha256&quot;:&quot;68c10966fe84406ee626034d58bfabd555df9f65f691204b7c46db24038da101&quot;,&quot;themeCssSha256&quot;:&quot;c80287a78d80ad63d27bd5ca348b2ef9a7e2f44da289e436be6484ea28a1b033&quot;}" adapterVersions="{&quot;diagramGenerator&quot;:&quot;2&quot;,&quot;drawioFlowchart&quot;:&quot;1&quot;,&quot;drawioGantt&quot;:&quot;1&quot;,&quot;drawioSequence&quot;:&quot;1&quot;,&quot;drawioState&quot;:&quot;1&quot;}" mermaidType="sequence" generatedAt="2026-08-12T23:36:46.870Z" mermaidSource="sequenceDiagram&#10;  autonumber&#10;  participant Runner as agent loop&#10;  participant PG as Postgres&#10;  actor Reviewer&#10;  participant API as approval route&#10;  participant Queue as pg-boss agent-resume&#10;  participant Worker as continuation worker&#10;  participant Tool as native/MCP tool&#10;&#10;  Runner-&gt;&gt;Runner: tool requires approval&#10;  Runner-&gt;&gt;PG: TX approval step + approval row + resume_cursor + suspended&#10;  Runner--&gt;&gt;Reviewer: reattach SSE / inbox shows pending&#10;  Reviewer-&gt;&gt;API: allow or deny + note&#10;  API-&gt;&gt;API: require agents:execute / live user capability&#10;  API-&gt;&gt;PG: TX decision + actor + step + run queued&#10;  API--&gt;&gt;Reviewer: 202 queued continuation&#10;  API-&gt;&gt;Queue: idempotent AgentResumeJob&#10;  Queue-&gt;&gt;Worker: {workspaceId, runId, approvalId}&#10;  Worker-&gt;&gt;PG: TX claim queued to running + load decided approval/cursor&#10;  alt allow&#10;    Worker-&gt;&gt;Tool: IO execute pending call&#10;    Tool--&gt;&gt;Worker: result&#10;  else deny&#10;    Worker-&gt;&gt;PG: record structured tool denial&#10;  end&#10;  Worker-&gt;&gt;Runner: continue model loop from cursor&#10;  Runner-&gt;&gt;PG: terminal output or another suspension">
          <mxCell parent="0"/>
        </object>
        <object id="c:i16" label="alt [allow] / [deny]" mermaidId="i16" mermaidShape="frame">
          <mxCell parent="1" vertex="1" style="collapsible=0;container=1;dashed=1;fillColor=none;fontColor=#333333;html=1;recursiveResize=0;rounded=0;strokeColor=#9370DB;whiteSpace=wrap;">
            <mxGeometry x="771" y="635" width="1357" height="240" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:Tool" label="native/MCP tool" mermaidId="Tool" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="2042" y="0" width="150" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:Worker" label="continuation worker" mermaidId="Worker" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="1785" y="0" width="170" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:Queue" label="pg-boss agent-resume" mermaidId="Queue" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="1455" y="0" width="194" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:API" label="approval route" mermaidId="API" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="1183" y="0" width="150" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:PG" label="Postgres" mermaidId="PG" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="707" y="0" width="150" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:Runner" label="agent loop" mermaidId="Runner" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#eaeaea;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=#666;whiteSpace=wrap;">
            <mxGeometry x="0" y="0" width="150" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="n:Reviewer" label="Reviewer" mermaidId="Reviewer" mermaidShape="participant">
          <mxCell parent="1" vertex="1" style="fillColor=#ECECFF;fontColor=#333333;html=1;participant=umlActor;shape=umlLifeline;strokeColor=rgb(147, 112, 219);whiteSpace=wrap;">
            <mxGeometry x="964" y="-5" width="36" height="65" as="geometry"/>
          </mxCell>
        </object>
        <object id="e:lifeline:Tool" label="" mermaidId="lifeline:Tool" mermaidKind="lifeline">
          <mxCell parent="1" source="n:Tool" target="n:Tool" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="2117" y="65" as="sourcePoint"/>
              <mxPoint x="2117" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:Worker" label="" mermaidId="lifeline:Worker" mermaidKind="lifeline">
          <mxCell parent="1" source="n:Worker" target="n:Worker" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1870" y="65" as="sourcePoint"/>
              <mxPoint x="1870" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:Queue" label="" mermaidId="lifeline:Queue" mermaidKind="lifeline">
          <mxCell parent="1" source="n:Queue" target="n:Queue" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1552" y="65" as="sourcePoint"/>
              <mxPoint x="1552" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:API" label="" mermaidId="lifeline:API" mermaidKind="lifeline">
          <mxCell parent="1" source="n:API" target="n:API" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1258" y="65" as="sourcePoint"/>
              <mxPoint x="1258" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:Reviewer" label="" mermaidId="lifeline:Reviewer" mermaidKind="lifeline">
          <mxCell parent="1" source="n:Reviewer" target="n:Reviewer" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="982" y="80" as="sourcePoint"/>
              <mxPoint x="982" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:PG" label="" mermaidId="lifeline:PG" mermaidKind="lifeline">
          <mxCell parent="1" source="n:PG" target="n:PG" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="782" y="65" as="sourcePoint"/>
              <mxPoint x="782" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:lifeline:Runner" label="" mermaidId="lifeline:Runner" mermaidKind="lifeline">
          <mxCell parent="1" source="n:Runner" target="n:Runner" edge="1" style="dashed=1;dashPattern=4 4;edgeStyle=none;endArrow=none;endFill=0;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#999;strokeWidth=0.5;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="75" y="65" as="sourcePoint"/>
              <mxPoint x="75" y="995" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i1" label="tool requires approval" mermaidId="i1" mermaidKind="message">
          <mxCell parent="1" source="n:Runner" target="n:Runner" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="76" y="115" as="sourcePoint"/>
              <mxPoint x="76" y="135" as="targetPoint"/>
              <Array as="points">
                <mxPoint x="136" y="105"/>
                <mxPoint x="136" y="145"/>
              </Array>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i2" label="TX approval step + approval row + resume_cursor + suspended" mermaidId="i2" mermaidKind="message">
          <mxCell parent="1" source="n:Runner" target="n:PG" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="82" y="195" as="sourcePoint"/>
              <mxPoint x="778" y="195" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i3" label="reattach SSE / inbox shows pending" mermaidId="i3" mermaidKind="message">
          <mxCell parent="1" source="n:Runner" target="n:Reviewer" edge="1" style="dashed=1;dashPattern=3  3;edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="82" y="245" as="sourcePoint"/>
              <mxPoint x="978" y="245" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i4" label="allow or deny + note" mermaidId="i4" mermaidKind="message">
          <mxCell parent="1" source="n:Reviewer" target="n:API" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="989" y="295" as="sourcePoint"/>
              <mxPoint x="1254" y="295" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i5" label="require agents:execute / live user capability" mermaidId="i5" mermaidKind="message">
          <mxCell parent="1" source="n:API" target="n:API" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1259" y="345" as="sourcePoint"/>
              <mxPoint x="1259" y="365" as="targetPoint"/>
              <Array as="points">
                <mxPoint x="1319" y="335"/>
                <mxPoint x="1319" y="375"/>
              </Array>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i6" label="TX decision + actor + step + run queued" mermaidId="i6" mermaidKind="message">
          <mxCell parent="1" source="n:API" target="n:PG" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1263" y="425" as="sourcePoint"/>
              <mxPoint x="786" y="425" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i7" label="202 queued continuation" mermaidId="i7" mermaidKind="message">
          <mxCell parent="1" source="n:API" target="n:Reviewer" edge="1" style="dashed=1;dashPattern=3  3;edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1263" y="475" as="sourcePoint"/>
              <mxPoint x="986" y="475" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i8" label="idempotent AgentResumeJob" mermaidId="i8" mermaidKind="message">
          <mxCell parent="1" source="n:API" target="n:Queue" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1265" y="525" as="sourcePoint"/>
              <mxPoint x="1548" y="525" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i9" label="{workspaceId, runId, approvalId}" mermaidId="i9" mermaidKind="message">
          <mxCell parent="1" source="n:Queue" target="n:Worker" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1559" y="575" as="sourcePoint"/>
              <mxPoint x="1866" y="575" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i10" label="TX claim queued to running + load decided approval/cursor" mermaidId="i10" mermaidKind="message">
          <mxCell parent="1" source="n:Worker" target="n:PG" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1875" y="625" as="sourcePoint"/>
              <mxPoint x="786" y="625" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i12" label="IO execute pending call" mermaidId="i12" mermaidKind="message">
          <mxCell parent="1" source="n:Worker" target="n:Tool" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1877" y="720" as="sourcePoint"/>
              <mxPoint x="2113" y="720" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i13" label="result" mermaidId="i13" mermaidKind="message">
          <mxCell parent="1" source="n:Tool" target="n:Worker" edge="1" style="dashed=1;dashPattern=3  3;edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="2122" y="770" as="sourcePoint"/>
              <mxPoint x="1874" y="770" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i15" label="record structured tool denial" mermaidId="i15" mermaidKind="message">
          <mxCell parent="1" source="n:Worker" target="n:PG" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1875" y="865" as="sourcePoint"/>
              <mxPoint x="786" y="865" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i17" label="continue model loop from cursor" mermaidId="i17" mermaidKind="message">
          <mxCell parent="1" source="n:Worker" target="n:Runner" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="1875" y="925" as="sourcePoint"/>
              <mxPoint x="79" y="925" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
        <object id="e:i18" label="terminal output or another suspension" mermaidId="i18" mermaidKind="message">
          <mxCell parent="1" source="n:Runner" target="n:PG" edge="1" style="edgeStyle=none;endArrow=block;endFill=1;html=1;jettySize=auto;orthogonalLoop=1;rounded=0;strokeColor=#333333;strokeWidth=2;">
            <mxGeometry relative="1" as="geometry">
              <mxPoint x="82" y="975" as="sourcePoint"/>
              <mxPoint x="778" y="975" as="targetPoint"/>
            </mxGeometry>
          </mxCell>
        </object>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>
