{
  "name": "[Strategy Drift] GitHub Issues Intelligence",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 */4 * * *"
            }
          ]
        }
      },
      "id": "gii-01",
      "name": "Every 4 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        200,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const staticData = $getWorkflowStaticData('global');\nconst lastRun = staticData.last_run_at\n  ? new Date(staticData.last_run_at)\n  : new Date(Date.now() - 24 * 60 * 60 * 1000);\nstaticData.last_run_at = new Date().toISOString();\nreturn [{\n  json: {\n    since: lastRun.toISOString().split('.')[0] + 'Z'\n  }\n}];"
      },
      "id": "gii-02",
      "name": "Get Time Window",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        420,
        400
      ]
    },
    {
      "parameters": {
        "url": "https://api.github.com/search/issues",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "=repo:n8n-io/n8n+is:issue+updated:>={{ $json.since }}"
            },
            {
              "name": "sort",
              "value": "updated"
            },
            {
              "name": "order",
              "value": "desc"
            },
            {
              "name": "per_page",
              "value": "50"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github+json"
            }
          ]
        },
        "options": {}
      },
      "id": "gii-03",
      "name": "Fetch Updated Issues",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        200
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "https://api.github.com/search/issues",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "repo:n8n-io/n8n+is:issue+is:open+sort:reactions-+1-desc"
            },
            {
              "name": "per_page",
              "value": "30"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github+json"
            }
          ]
        },
        "options": {}
      },
      "id": "gii-04",
      "name": "Fetch Top Reacted Issues",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        400
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "https://api.github.com/search/issues",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "repo:n8n-io/n8n+is:issue+is:open+MCP+OR+agent+OR+memory"
            },
            {
              "name": "sort",
              "value": "updated"
            },
            {
              "name": "per_page",
              "value": "30"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github+json"
            }
          ]
        },
        "options": {}
      },
      "id": "gii-05",
      "name": "Fetch MCP Issues",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        600
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "append",
        "options": {}
      },
      "id": "gii-06",
      "name": "Merge Updated+Reacted",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "options": {}
      },
      "id": "gii-07",
      "name": "Merge All Sources",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        900,
        500
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const allItems = $input.all();\nconst seen = new Set();\nconst deduped = [];\n\nfor (const item of allItems) {\n  // Handle GitHub Search API response: items are in .items array\n  const rawItems = item.json.items || [item.json];\n  for (const raw of rawItems) {\n    const number = raw.number;\n    if (!number || seen.has(number)) continue;\n    seen.add(number);\n\n    const labels = (raw.labels || []).map(l => typeof l === 'string' ? l : l.name || '');\n    const reactionsTotal = (raw.reactions ? (raw.reactions['+1'] || 0) + (raw.reactions['-1'] || 0) + (raw.reactions.laugh || 0) + (raw.reactions.hooray || 0) + (raw.reactions.confused || 0) + (raw.reactions.heart || 0) + (raw.reactions.rocket || 0) + (raw.reactions.eyes || 0) : 0) || raw.reactions?.total_count || 0;\n    const body = raw.body || '';\n\n    deduped.push({\n      json: {\n        number: number,\n        title: raw.title || '',\n        labels: labels,\n        reactions_total: reactionsTotal,\n        comments_count: raw.comments || 0,\n        html_url: raw.html_url || '',\n        created_at: raw.created_at || '',\n        updated_at: raw.updated_at || '',\n        body_excerpt: body.substring(0, 300)\n      }\n    });\n  }\n}\n\nif (deduped.length === 0) {\n  return [{ json: { _empty: true, number: 0, title: 'No issues found' } }];\n}\n\nreturn deduped;"
      },
      "id": "gii-08",
      "name": "Merge & Dedup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const items = $input.all().map(i => i.json);\n\n// Short-circuit if no real issues\nif (items.length === 1 && items[0]._empty) {\n  return [{ json: { prompt: 'No issues to classify.', issue_count: 0, issues: '[]' } }];\n}\n\nconst issueList = items.map((iss, idx) =>\n  '[' + (idx + 1) + '] #' + iss.number + ': ' + iss.title + '\\n  Labels: ' + (iss.labels || []).join(', ') + '\\n  Reactions: ' + iss.reactions_total + ' | Comments: ' + iss.comments_count + '\\n  ' + (iss.body_excerpt || '')\n).join('\\n\\n');\n\nreturn [{ json: { prompt: issueList, issue_count: items.length, issues: JSON.stringify(items) } }];"
      },
      "id": "gii-09",
      "name": "Build Classification Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1380,
        400
      ]
    },
    {
      "parameters": {
        "text": "={{ $json.prompt }}",
        "options": {
          "systemMessage": "You are a strategy intelligence analyst for n8n (AI Workforce OS).\n\nYou are given a batch of GitHub issues. For EACH issue, classify it:\n\nSTRATEGY LAYERS:\n- L1: Agent Runtime \u2014 issues about AI agents failing, crashing, losing context, error handling, retry logic, performance in production\n- L2: Skill Network \u2014 issues about MCP (Model Context Protocol), tool integrations, agent-to-tool connectivity, skill discovery\n- L3: Persistent Memory \u2014 issues about agent memory, chat memory, data persistence, context retention across sessions\n- L4: Agent Observability \u2014 issues about token usage visibility, execution tracing, cost tracking, debugging agent behavior\n- L5: Trust & Governance \u2014 issues about security, auth, compliance, privacy, RBAC, self-hosting trust\n- L0: Core Platform \u2014 issues about workflow engine, UI, triggers, non-AI nodes, infrastructure\n\nASSUMPTIONS IMPACTED:\n- A1: Capability Doubling \u2014 model capabilities double every ~7mo\n- A2: Integration Moats Gone \u2014 integrations alone are not defensible\n- A3: Speed > Scope \u2014 ship fast, iterate, narrow focus wins\n- A4: Governance Day 1 \u2014 build trust/compliance from start\n- A5: Workforce Metaphor \u2014 users think of AI as workers, not tools\n- A6: Community Is Moat \u2014 open source community is the real moat\n\nIMPACT DIRECTION:\n- Reinforces: This issue validates our strategy direction\n- Challenges: This issue suggests our strategy may be wrong\n- Ambiguous: Could go either way\n\nCOMMUNITY SEVERITY (based on reactions + impact):\n- Critical: >10 reactions OR regression OR data loss\n- High: 5-10 reactions OR security issue\n- Medium: 2-4 reactions OR notable pattern\n- Low: 0-1 reactions, isolated case\n\nFor EACH issue, respond with a JSON array:\n[\n  {\n    \"number\": 12345,\n    \"layer\": \"L2\",\n    \"assumptions\": [\"A2\", \"A3\"],\n    \"direction\": \"Reinforces\",\n    \"severity\": \"High\",\n    \"summary\": \"One-sentence strategic relevance\",\n    \"strategy_relevant\": true\n  },\n  ...\n]\n\nOnly set strategy_relevant=true for issues in L1-L5. L0 issues are strategy_relevant=false.\nBe specific in summaries \u2014 explain WHY this matters to the strategy.",
          "maxIterations": 10
        }
      },
      "id": "gii-10",
      "name": "AI: Strategy Classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        1620,
        400
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-haiku-4-5-20251001",
          "mode": "id"
        },
        "options": {
          "maxTokensToSample": 8192,
          "temperature": 0.2
        }
      },
      "id": "gii-11",
      "name": "Claude Haiku",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        1620,
        620
      ],
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const aiOutput = $input.first().json.output || $input.first().json.text || $input.first().json.response || '';\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse the JSON array from LLM response\nlet classifications = [];\ntry {\n  const jsonMatch = aiOutput.match(/\\[[\\s\\S]*\\]/);\n  if (jsonMatch) classifications = JSON.parse(jsonMatch[0]);\n} catch (e) {\n  return [{ json: { error: 'Failed to parse LLM response', raw: aiOutput, signals: [], dashboard: null, _type: 'dashboard' } }];\n}\n\n// Get original issues for enrichment\nlet originalIssues = [];\ntry {\n  originalIssues = JSON.parse($('Build Classification Prompt').first().json.issues || '[]');\n} catch (e) {\n  originalIssues = [];\n}\nconst issueMap = {};\nfor (const iss of (Array.isArray(originalIssues) ? originalIssues : [])) {\n  issueMap[iss.number] = iss;\n}\n\n// Aggregate by layer\nconst layerCounts = { L0: 0, L1: 0, L2: 0, L3: 0, L4: 0, L5: 0 };\nconst layerReactions = { L0: 0, L1: 0, L2: 0, L3: 0, L4: 0, L5: 0 };\nconst signals = [];\n\nfor (const c of classifications) {\n  const layer = c.layer || 'L0';\n  layerCounts[layer] = (layerCounts[layer] || 0) + 1;\n  const orig = issueMap[c.number] || {};\n  layerReactions[layer] = (layerReactions[layer] || 0) + (orig.reactions_total || 0);\n\n  if (c.strategy_relevant) {\n    signals.push({\n      signal_title: '[' + layer + '] #' + c.number + ': ' + (orig.title || 'Unknown'),\n      source: 'GitHub',\n      source_url: orig.html_url || 'https://github.com/n8n-io/n8n/issues/' + c.number,\n      assumptions_impacted: JSON.stringify(c.assumptions || []),\n      impact_direction: c.direction || 'Ambiguous',\n      severity: c.severity || 'Low',\n      summary: c.summary || '',\n      competitor: 'None',\n      detected_by: 'n8n Workflow'\n    });\n  }\n}\n\n// Trend tracking \u2014 store historical layer counts\nif (!staticData.layer_history) staticData.layer_history = [];\nconst now = new Date().toISOString().split('T')[0];\nstaticData.layer_history.push({\n  date: now,\n  counts: { ...layerCounts },\n  reactions: { ...layerReactions }\n});\n// Keep only last 90 days\nif (staticData.layer_history.length > 90) {\n  staticData.layer_history = staticData.layer_history.slice(-90);\n}\n\n// Spike detection \u2014 compare current counts to 7-day average\nconst recent7 = staticData.layer_history.slice(-7);\nconst avgCounts = {};\nconst spikes = [];\nfor (const layer of ['L1', 'L2', 'L3', 'L4', 'L5']) {\n  const avg = recent7.reduce((sum, d) => sum + (d.counts[layer] || 0), 0) / Math.max(recent7.length, 1);\n  avgCounts[layer] = Math.round(avg * 10) / 10;\n  if (layerCounts[layer] > avg * 2 && layerCounts[layer] >= 3) {\n    spikes.push({ layer, current: layerCounts[layer], average: avgCounts[layer] });\n  }\n}\n\n// Build dashboard data\nconst layerNames = {\n  L1: 'Agent Runtime', L2: 'Skill Network', L3: 'Persistent Memory',\n  L4: 'Agent Observability', L5: 'Trust & Governance', L0: 'Core Platform'\n};\nconst layerStatus = {};\nfor (const layer of ['L1', 'L2', 'L3', 'L4', 'L5']) {\n  const count = layerCounts[layer];\n  const reactions = layerReactions[layer];\n  let temp = 'Cool';\n  if (reactions > 30) temp = 'On Fire';\n  else if (reactions > 15) temp = 'Hot';\n  else if (reactions > 5) temp = 'Warm';\n\n  let status = 'GREEN';\n  if (count >= 10 || reactions > 30) status = 'RED';\n  else if (count >= 5 || reactions > 10) status = 'YELLOW';\n\n  layerStatus[layer] = { name: layerNames[layer], count, reactions, temp, status };\n}\n\n// Build QuickChart URL for layer distribution\nconst chartLabels = ['L1', 'L2', 'L3', 'L4', 'L5'];\nconst chartData = chartLabels.map(l => layerCounts[l]);\nconst chartReactions = chartLabels.map(l => layerReactions[l]);\nconst chartConfig = {\n  type: 'bar',\n  data: {\n    labels: chartLabels.map(l => layerNames[l]),\n    datasets: [\n      { label: 'Issues', data: chartData, backgroundColor: 'rgba(54, 162, 235, 0.8)' },\n      { label: 'Reactions', data: chartReactions, backgroundColor: 'rgba(255, 99, 132, 0.8)' }\n    ]\n  },\n  options: {\n    title: { display: true, text: 'GitHub Issues by Strategy Layer' },\n    scales: { yAxes: [{ ticks: { beginAtZero: true } }] }\n  }\n};\nconst chartUrl = 'https://quickchart.io/chart?w=600&h=350&c=' + encodeURIComponent(JSON.stringify(chartConfig));\n\n// Build trend chart from history\nconst trendDates = staticData.layer_history.slice(-14).map(d => d.date.slice(5));\nconst trendConfig = {\n  type: 'line',\n  data: {\n    labels: trendDates,\n    datasets: ['L1', 'L2', 'L3', 'L4', 'L5'].map((l, i) => ({\n      label: l + ': ' + layerNames[l],\n      data: staticData.layer_history.slice(-14).map(d => d.counts[l] || 0),\n      borderColor: ['#3498db', '#e74c3c', '#9b59b6', '#f39c12', '#2ecc71'][i],\n      fill: false,\n      tension: 0.3\n    }))\n  },\n  options: {\n    title: { display: true, text: 'Issue Trend by Layer (14-day)' },\n    scales: { yAxes: [{ ticks: { beginAtZero: true } }] }\n  }\n};\nconst trendChartUrl = 'https://quickchart.io/chart?w=700&h=350&c=' + encodeURIComponent(JSON.stringify(trendConfig));\n\n// Top issues by reactions (strategy-relevant only)\nconst topIssues = signals\n  .sort((a, b) => {\n    const aNum = parseInt((a.source_url || '').match(/\\/(\\d+)$/)?.[1]) || 0;\n    const bNum = parseInt((b.source_url || '').match(/\\/(\\d+)$/)?.[1]) || 0;\n    const aReactions = (issueMap[aNum] || {}).reactions_total || 0;\n    const bReactions = (issueMap[bNum] || {}).reactions_total || 0;\n    return bReactions - aReactions;\n  })\n  .slice(0, 10);\n\nconst dashboard = {\n  date: now,\n  layerCounts,\n  layerReactions,\n  layerStatus,\n  spikes,\n  chartUrl,\n  trendChartUrl,\n  totalIssuesClassified: classifications.length,\n  strategyRelevantCount: signals.length,\n  topIssues: topIssues.map(s => s.signal_title).join('\\n')\n};\n\n// Return signals as individual items for sub-workflow, plus dashboard as last item\nconst output = signals.map(s => ({ json: { ...s, _type: 'signal' } }));\noutput.push({ json: { ...dashboard, _type: 'dashboard' } });\n\nreturn output;"
      },
      "id": "gii-12",
      "name": "Parse & Aggregate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1860,
        400
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "type-signal-check",
              "leftValue": "={{ $json._type }}",
              "rightValue": "signal",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "gii-13",
      "name": "Is Signal?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        2100,
        300
      ]
    },
    {
      "parameters": {
        "workflowId": "={{ $vars.SIGNAL_TO_NOTION_WORKFLOW_ID }}",
        "options": {}
      },
      "id": "gii-14",
      "name": "Write to Notion",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.1,
      "position": [
        2340,
        200
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const item = $input.first().json;\nconst now = item.date || new Date().toISOString().split('T')[0];\nconst layerStatus = item.layerStatus || {};\nconst spikes = item.spikes || [];\nconst topIssues = item.topIssues || 'None';\nconst chartUrl = item.chartUrl || '';\nconst trendChartUrl = item.trendChartUrl || '';\nconst totalClassified = item.totalIssuesClassified || 0;\nconst strategyRelevant = item.strategyRelevantCount || 0;\n\n// Build layer health table rows\nconst statusIcon = { GREEN: '\ud83d\udfe2', YELLOW: '\ud83d\udfe1', RED: '\ud83d\udd34' };\nlet tableRows = '';\nfor (const layer of ['L1', 'L2', 'L3', 'L4', 'L5']) {\n  const s = layerStatus[layer];\n  if (!s) continue;\n  const icon = statusIcon[s.status] || '\u26aa';\n  tableRows += '| ' + layer + ': ' + s.name + ' | ' + icon + ' | ' + s.count + ' | ' + s.reactions + ' | ' + s.temp + ' |\\n';\n}\n\n// Build spike section\nlet spikeSection = 'No spikes detected.';\nif (spikes.length > 0) {\n  spikeSection = spikes.map(sp =>\n    '- **' + sp.layer + '**: ' + sp.current + ' issues (7-day avg: ' + sp.average + ') \u2014 2x+ spike detected'\n  ).join('\\n');\n}\n\n// Build full dashboard markdown\nconst content = 'Last updated: ' + now + '\\n'\n  + 'Issues classified: ' + totalClassified + ' | Strategy-relevant: ' + strategyRelevant + '\\n\\n'\n  + '## Layer Health\\n\\n'\n  + '| Layer | Status | Issues | Reactions | Temperature |\\n'\n  + '|-------|--------|--------|-----------|-------------|\\n'\n  + tableRows + '\\n'\n  + '## Issue Distribution\\n\\n'\n  + '![Chart](' + chartUrl + ')\\n\\n'\n  + '## Issue Trends (14-day)\\n\\n'\n  + '![Trend](' + trendChartUrl + ')\\n\\n'\n  + '## Top Community Asks (Strategy-Relevant)\\n\\n'\n  + topIssues + '\\n\\n'\n  + '## Spike Alerts\\n\\n'\n  + spikeSection;\n\nreturn [{ json: { content, title: 'GitHub Issues Intelligence \u2014 ' + now, spikes, spikeCount: spikes.length } }];"
      },
      "id": "gii-15",
      "name": "Build Dashboard Content",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2100,
        600
      ]
    },
    {
      "parameters": {
        "resource": "page",
        "operation": "update",
        "pageId": {
          "__rl": true,
          "value": "3282d8a2-d60e-81c6-a1e9-d6b98550ac80",
          "mode": "id"
        },
        "title": "={{ $json.title }}",
        "body": {
          "contentUi": {
            "contentValues": [
              {
                "content": "={{ $json.content }}"
              }
            ]
          }
        }
      },
      "id": "gii-16",
      "name": "Update Command Center",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        2340,
        600
      ],
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "spike-count-check",
              "leftValue": "={{ $json.spikeCount }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "gii-17",
      "name": "Has Spikes?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        2100,
        800
      ]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "#strategy-signals",
          "mode": "name"
        },
        "text": "={{ '\u26a0\ufe0f *Strategy Layer Spike Detected*\\n\\n' + ($json.spikes || []).map(sp => '\u2022 *' + sp.layer + '*: ' + sp.current + ' issues (7-day avg: ' + sp.average + ') \u2014 2x+ spike').join('\\n') + '\\n\\nCheck the GitHub Issues Intelligence dashboard for details.' }}",
        "otherOptions": {
          "mrkdwn": true
        }
      },
      "id": "gii-18",
      "name": "Slack: Spike Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        2340,
        800
      ],
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Every 4 Hours": {
      "main": [
        [
          {
            "node": "Get Time Window",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Time Window": {
      "main": [
        [
          {
            "node": "Fetch Updated Issues",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Top Reacted Issues",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch MCP Issues",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Updated Issues": {
      "main": [
        [
          {
            "node": "Merge Updated+Reacted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Top Reacted Issues": {
      "main": [
        [
          {
            "node": "Merge Updated+Reacted",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Updated+Reacted": {
      "main": [
        [
          {
            "node": "Merge All Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch MCP Issues": {
      "main": [
        [
          {
            "node": "Merge All Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge All Sources": {
      "main": [
        [
          {
            "node": "Merge & Dedup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge & Dedup": {
      "main": [
        [
          {
            "node": "Build Classification Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Classification Prompt": {
      "main": [
        [
          {
            "node": "AI: Strategy Classifier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI: Strategy Classifier": {
      "main": [
        [
          {
            "node": "Parse & Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Haiku": {
      "ai_languageModel": [
        [
          {
            "node": "AI: Strategy Classifier",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Aggregate": {
      "main": [
        [
          {
            "node": "Is Signal?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Signal?": {
      "main": [
        [
          {
            "node": "Write to Notion",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Dashboard Content",
            "type": "main",
            "index": 0
          },
          {
            "node": "Has Spikes?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Dashboard Content": {
      "main": [
        [
          {
            "node": "Update Command Center",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Spikes?": {
      "main": [
        [
          {
            "node": "Slack: Spike Alert",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "strategy-drift"
    },
    {
      "name": "github-intelligence"
    }
  ],
  "meta": {
    "templateCredsSetupCompleted": false
  }
}