{
  "name": "Approvals \u2014 Request Handler (GAL-109)",
  "nodes": [
    {
      "id": "webhook-trigger",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "approval-request",
        "responseMode": "responseNode",
        "options": {}
      }
    },
    {
      "id": "normalize",
      "name": "Normalize Inputs",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        440,
        300
      ],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "assignments": {
          "assignments": [
            {
              "id": "4f437c84-46d8-4619-a2ab-bad0a1c48ad2",
              "name": "idempotency_key",
              "value": "={{ $json.body.idempotency_key }}",
              "type": "string"
            },
            {
              "id": "a122b7a6-8003-461a-9ebb-4552fb7ad4dc",
              "name": "agent",
              "value": "={{ $json.body.agent }}",
              "type": "string"
            },
            {
              "id": "0f917e9b-5aca-42ed-90a4-1a5ec0e39c98",
              "name": "gate_id",
              "value": "={{ $json.body.gate_id }}",
              "type": "string"
            },
            {
              "id": "95913fba-84ee-4386-8645-887de03fad38",
              "name": "description",
              "value": "={{ $json.body.description }}",
              "type": "string"
            },
            {
              "id": "c1b91574-71da-4599-a51d-b47c02339121",
              "name": "detail",
              "value": "={{ $json.body.detail || '' }}",
              "type": "string"
            },
            {
              "id": "4a1a20b2-d912-44ec-b89a-3d7136df3499",
              "name": "risk_level",
              "value": "={{ $json.body.risk_level || 'medium' }}",
              "type": "string"
            },
            {
              "id": "f84a1e45-cfe7-4c77-8bc9-0957e2c31470",
              "name": "session_id",
              "value": "={{ $json.body.session_id || '' }}",
              "type": "string"
            },
            {
              "id": "dc0fbe13-54b6-42d3-b29c-a8559bd02a0a",
              "name": "dry_run",
              "value": "={{ $json.query && $json.query.dry_run === 'true' }}",
              "type": "boolean"
            },
            {
              "id": "4a14658f-9ecf-4a96-b36c-db51e92a7cc1",
              "name": "timeout_minutes",
              "value": "={{ ({\"deploy_billing_auth_payments\": 10, \"db_migration\": 10, \"dns_change\": 10, \"rls_policy_change\": 10, \"free_tier_exceed\": 15, \"new_third_party_service\": 15, \"regulated_content\": 30, \"incident_disclosure\": 5, \"partner_commitment\": 30, \"destructive_op\": 5})[$json.body.gate_id] || 10 }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "validate",
      "name": "Validate Payload",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        640,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "2bb30a59-eed6-4a26-90ee-d88a05f01a1a",
              "leftValue": "={{ $json.idempotency_key }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            },
            {
              "id": "4fdb2020-2903-4513-b951-a91e4f63ef34",
              "leftValue": "={{ $json.agent }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            },
            {
              "id": "35f0ec5d-0f51-466b-bcc9-dfc025752e30",
              "leftValue": "={{ $json.gate_id }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            },
            {
              "id": "e8e8c714-26e7-4512-9366-6a1fd9b7b0bd",
              "leftValue": "={{ $json.description }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "respond-400",
      "name": "Respond: 400 Bad Request",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        840,
        460
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({error: \"missing required field(s): idempotency_key, agent, gate_id, description\"}) }}",
        "options": {
          "responseCode": 400
        }
      }
    },
    {
      "id": "check-idempotency",
      "name": "Check Idempotency",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        840,
        300
      ],
      "parameters": {
        "method": "GET",
        "url": "=https://jiidzeympaalzljyqvjq.supabase.co/rest/v1/approval_requests?idempotency_key=eq.{{ $json.idempotency_key }}&select=*",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Accept-Profile",
              "value": "ops"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      },
      "alwaysOutputData": true
    },
    {
      "id": "wrap-idempotency",
      "name": "Wrap Idempotency Result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        940,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// n8n's HTTP Request splits JSON arrays into items; each item's json is a single row.\n// With alwaysOutputData=true, a truly empty response still emits 1 item (possibly empty json).\n// Filter by idempotency_key presence to distinguish real rows from the phantom item.\nconst items = $input.all();\nconst rows = items.map(i => i.json).filter(r => r && typeof r === 'object' && r.idempotency_key);\nreturn [{ json: { rows, row_count: rows.length, first_row: rows[0] || null } }];\n"
      }
    },
    {
      "id": "route-existing",
      "name": "Existing?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1040,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "494aebd8-2ed0-4b5a-a209-fe5de76fd5c5",
              "leftValue": "={{ $json.row_count }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "route-pending-or-resolved",
      "name": "Pending or Resolved?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1240,
        200
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cce91852-ba4b-4a6a-8031-52dcde3195c7",
              "leftValue": "={{ $json.first_row.status }}",
              "rightValue": "pending",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "respond-409",
      "name": "Respond: 409 Pending Dup",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1440,
        100
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({error: \"duplicate pending request\", idempotency_key: $json.first_row.idempotency_key, status: \"pending\"}) }}",
        "options": {
          "responseCode": 409
        }
      }
    },
    {
      "id": "respond-cached",
      "name": "Respond: Cached Outcome",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1440,
        300
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({gate_id: $json.first_row.gate_id, approved: $json.first_row.status === \"approved\", approver: $json.first_row.approver, timestamp: $json.first_row.resolved_at, status: $json.first_row.status, dry_run: $json.first_row.is_dry_run, cached: true}) }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "insert-row",
      "name": "Insert Pending Row",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1240,
        500
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://jiidzeympaalzljyqvjq.supabase.co/rest/v1/approval_requests",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Content-Profile",
              "value": "ops"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=representation"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "idempotency_key",
              "value": "={{ $('Normalize Inputs').item.json.idempotency_key }}"
            },
            {
              "name": "agent",
              "value": "={{ $('Normalize Inputs').item.json.agent }}"
            },
            {
              "name": "gate_id",
              "value": "={{ $('Normalize Inputs').item.json.gate_id }}"
            },
            {
              "name": "description",
              "value": "={{ $('Normalize Inputs').item.json.description }}"
            },
            {
              "name": "detail",
              "value": "={{ $('Normalize Inputs').item.json.detail }}"
            },
            {
              "name": "risk_level",
              "value": "={{ $('Normalize Inputs').item.json.risk_level }}"
            },
            {
              "name": "session_id",
              "value": "={{ $('Normalize Inputs').item.json.session_id }}"
            },
            {
              "name": "is_dry_run",
              "value": "={{ $('Normalize Inputs').item.json.dry_run }}"
            },
            {
              "name": "status",
              "value": "pending"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "send-telegram",
      "name": "Send Telegram Approval",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1440,
        500
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN_OPS }}/sendMessage",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  chat_id: $env.TELEGRAM_CHAT_ID,\n  text: `\\ud83d\\udd12 Human Gate \u2014 ${$('Normalize Inputs').item.json.gate_id}\\n\\nAgent: ${$('Normalize Inputs').item.json.agent}\\nAction: ${$('Normalize Inputs').item.json.description}\\n\\n${$('Normalize Inputs').item.json.detail}\\n\\nRisk: ${$('Normalize Inputs').item.json.risk_level}\\n\\n\\u23f0 Auto-rejects in ${$('Normalize Inputs').item.json.timeout_minutes}m.${$('Normalize Inputs').item.json.dry_run ? '\\n\\n(DRY-RUN \u2014 not actually blocking)' : ''}`,\n  reply_markup: {\n    inline_keyboard: [[\n      {text: '\\u2705 Approve', callback_data: `approve:${$('Insert Pending Row').item.json.id}`},\n      {text: '\\u274c Reject', callback_data: `reject:${$('Insert Pending Row').item.json.id}`}\n    ]]\n  }\n}) }}",
        "options": {}
      }
    },
    {
      "id": "store-msgid",
      "name": "Store Message ID",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        620
      ],
      "parameters": {
        "method": "PATCH",
        "url": "=https://jiidzeympaalzljyqvjq.supabase.co/rest/v1/approval_requests?idempotency_key=eq.{{ $('Normalize Inputs').item.json.idempotency_key }}",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Content-Profile",
              "value": "ops"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=representation"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "telegram_message_id",
              "value": "={{ $json.result.message_id }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    },
    {
      "id": "is-dry-run",
      "name": "Is Dry Run?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1740,
        500
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "903d928c-cdf9-4e0a-acbc-e9f3666a3d49",
              "leftValue": "={{ $('Normalize Inputs').item.json.dry_run }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "respond-dry-run",
      "name": "Respond: Dry Run",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1840,
        400
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({gate_id: $('Normalize Inputs').item.json.gate_id, approved: false, status: \"pending\", dry_run: true, message: \"Dry run \u2014 not blocking\"}) }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "poll-wait",
      "name": "Poll Wait 3s",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        1840,
        600
      ],
      "parameters": {
        "amount": 3,
        "unit": "seconds"
      }
    },
    {
      "id": "check-status",
      "name": "Check Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2040,
        600
      ],
      "parameters": {
        "method": "GET",
        "url": "=https://jiidzeympaalzljyqvjq.supabase.co/rest/v1/approval_requests?idempotency_key=eq.{{ $('Normalize Inputs').item.json.idempotency_key }}&select=*",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Accept-Profile",
              "value": "ops"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "is-resolved",
      "name": "Is Resolved?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2240,
        600
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c56e0f5f-7cb5-4723-948c-e14b22d2b575",
              "leftValue": "={{ $json.status }}",
              "rightValue": "pending",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "check-timeout",
      "name": "Timeout Reached?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2240,
        800
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "45da5960-7860-4d5f-92b6-b90c189c2439",
              "leftValue": "={{ (new Date() - new Date($('Check Status').item.json.requested_at)) / 60000 }}",
              "rightValue": "={{ $('Normalize Inputs').item.json.timeout_minutes }}",
              "operator": {
                "type": "number",
                "operation": "gte"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "update-timeout",
      "name": "Update: Timeout",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2440,
        900
      ],
      "parameters": {
        "method": "PATCH",
        "url": "=https://jiidzeympaalzljyqvjq.supabase.co/rest/v1/approval_requests?idempotency_key=eq.{{ $('Normalize Inputs').item.json.idempotency_key }}&status=eq.pending",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SB_LSA_PRO_SR }}"
            },
            {
              "name": "Content-Profile",
              "value": "ops"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=representation"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "status",
              "value": "timeout"
            },
            {
              "name": "resolved_at",
              "value": "={{ new Date().toISOString() }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "edit-timeout-msg",
      "name": "Edit Original: Timeout",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2640,
        800
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN_OPS }}/editMessageText",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({chat_id: $env.TELEGRAM_CHAT_ID, message_id: $('Check Status').item.json.telegram_message_id, text: `\\ud83d\\udd12 Human Gate \u2014 ${$('Normalize Inputs').item.json.gate_id}\\n\\nAgent: ${$('Normalize Inputs').item.json.agent}\\nAction: ${$('Normalize Inputs').item.json.description}\\n\\nRisk: ${$('Normalize Inputs').item.json.risk_level}\\n\\n\\u23f0 AUTO-REJECTED \u2014 no response in ${$('Normalize Inputs').item.json.timeout_minutes}m`}) }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    },
    {
      "id": "send-timeout-msg",
      "name": "Send Timeout Notice",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2840,
        900
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN_OPS }}/sendMessage",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({chat_id: $env.TELEGRAM_CHAT_ID, text: `\\u23f0 Auto-rejected: ${$('Normalize Inputs').item.json.description} (no response in ${$('Normalize Inputs').item.json.timeout_minutes}m)` + ($('Normalize Inputs').item.json.gate_id === 'incident_disclosure' ? '\\n\\n\\ud83d\\udea8 INCIDENT DISCLOSURE \u2014 immediate visibility required' : '')}) }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    },
    {
      "id": "respond-timeout",
      "name": "Respond: Timeout",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        3040,
        900
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({gate_id: $('Normalize Inputs').item.json.gate_id, approved: false, status: \"timeout\", dry_run: false, message: \"Auto-rejected on timeout\"}) }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "respond-resolved",
      "name": "Respond: Resolved",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2440,
        500
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({gate_id: $('Check Status').item.json.gate_id, approved: $('Check Status').item.json.status === \"approved\", approver: $('Check Status').item.json.approver, timestamp: $('Check Status').item.json.resolved_at, status: $('Check Status').item.json.status, dry_run: $('Check Status').item.json.is_dry_run}) }}",
        "options": {
          "responseCode": 200
        }
      }
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Normalize Inputs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Inputs": {
      "main": [
        [
          {
            "node": "Validate Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Payload": {
      "main": [
        [
          {
            "node": "Check Idempotency",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond: 400 Bad Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Idempotency": {
      "main": [
        [
          {
            "node": "Wrap Idempotency Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wrap Idempotency Result": {
      "main": [
        [
          {
            "node": "Existing?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Existing?": {
      "main": [
        [
          {
            "node": "Pending or Resolved?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Insert Pending Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pending or Resolved?": {
      "main": [
        [
          {
            "node": "Respond: 409 Pending Dup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond: Cached Outcome",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Pending Row": {
      "main": [
        [
          {
            "node": "Send Telegram Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Telegram Approval": {
      "main": [
        [
          {
            "node": "Store Message ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Message ID": {
      "main": [
        [
          {
            "node": "Is Dry Run?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Dry Run?": {
      "main": [
        [
          {
            "node": "Respond: Dry Run",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Poll Wait 3s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Wait 3s": {
      "main": [
        [
          {
            "node": "Check Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Status": {
      "main": [
        [
          {
            "node": "Is Resolved?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Resolved?": {
      "main": [
        [
          {
            "node": "Respond: Resolved",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Timeout Reached?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Timeout Reached?": {
      "main": [
        [
          {
            "node": "Update: Timeout",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Poll Wait 3s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update: Timeout": {
      "main": [
        [
          {
            "node": "Edit Original: Timeout",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Original: Timeout": {
      "main": [
        [
          {
            "node": "Send Timeout Notice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Timeout Notice": {
      "main": [
        [
          {
            "node": "Respond: Timeout",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner"
  }
}