{
  "id": "XJYbT2WKSaNhfE5n",
  "name": "AI Governance Policy Generator",
  "tags": [],
  "nodes": [
    {
      "id": "f731114b-3402-46fa-a414-2e4e62acb5c5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        416
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 320,
        "content": "## Receive intake request\n\nCaptures the policy request, validates and enriches submitted data, and sends an immediate webhook response before longer processing begins."
      },
      "typeVersion": 1
    },
    {
      "id": "0f07c7e9-194a-4566-b384-ac017623613c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 464,
        "content": "## Research EU AI Act\n\nUses an AI agent with OpenAI and SerpAPI search to gather EU AI Act context for the governance policy."
      },
      "typeVersion": 1
    },
    {
      "id": "6201ca51-053a-4b34-8cfd-9386074bcdf1",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        720
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 400,
        "content": "## Research ABA ethics\n\nUses an AI agent with OpenAI and SerpAPI search to collect ABA ethics guidance relevant to AI governance."
      },
      "typeVersion": 1
    },
    {
      "id": "5209c52a-a902-4a63-8f9f-b650a1b49fb9",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 464,
        "content": "## Research case law\n\nUses an AI agent with OpenAI and SerpAPI search to identify relevant case law, sanctions, and enforcement examples."
      },
      "typeVersion": 1
    },
    {
      "id": "cc1b40bb-0e87-4de0-9901-e4ed549eb258",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        1152
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 464,
        "content": "## Research jurisdiction rules\n\nUses an AI agent with OpenAI and SerpAPI search to gather jurisdiction-specific AI regulations and compliance requirements."
      },
      "typeVersion": 1
    },
    {
      "id": "cf6904bd-87c1-4df0-bf8d-e25bc9300272",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        112
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 384,
        "content": "## Aggregate research findings\n\nMerges all parallel research streams and structures the combined results for downstream policy generation."
      },
      "typeVersion": 1
    },
    {
      "id": "f7e2f583-9cff-4bf7-acd0-582bb0f70ace",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2000,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 448,
        "content": "## Generate executive summary\n\nCreates the executive summary deliverable using the aggregated research and a dedicated OpenAI model."
      },
      "typeVersion": 1
    },
    {
      "id": "22946bc7-4e83-461d-86d0-fe21637d386b",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        736
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 448,
        "content": "## Generate discussion guide\n\nCreates a discussion guide for reviewers or stakeholders using the aggregated research and a dedicated OpenAI model."
      },
      "typeVersion": 1
    },
    {
      "id": "be435a7c-5fbd-40dd-8db5-97747251b6ec",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        272
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 448,
        "content": "## Generate draft policy\n\nCreates the main AI governance policy draft using the aggregated research and a dedicated OpenAI model."
      },
      "typeVersion": 1
    },
    {
      "id": "8585d745-5433-45ac-8021-55e9b98188d7",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        1232
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 480,
        "content": "## Generate implementation roadmap\n\nCreates an implementation roadmap using the aggregated research and a dedicated OpenAI model."
      },
      "typeVersion": 1
    },
    {
      "id": "2a73bfb4-f19b-4efe-82b7-37ff842738ac",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 384,
        "content": "## Compile and convert PDF\n\nMerges generated deliverables, compiles them into branded HTML, and sends the HTML to a PDF conversion service."
      },
      "typeVersion": 1
    },
    {
      "id": "05ce2b80-af60-4dc2-9b83-413465c62d73",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2976,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 320,
        "content": "## Upload and collect links\n\nUploads the PDF to SharePoint, builds share links from the upload response, and aggregates all generated links."
      },
      "typeVersion": 1
    },
    {
      "id": "b6b12395-726e-46e4-b6be-e71e7862240c",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3488,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 320,
        "content": "## Send review email\n\nPrepares the internal review email containing SharePoint links and sends it through Outlook."
      },
      "typeVersion": 1
    },
    {
      "id": "9f5eba69-461b-4754-80c6-2b2f86d970cc",
      "name": "When Form Submitted",
      "type": "n8n-nodes-base.webhook",
      "position": [
        608,
        576
      ],
      "parameters": {
        "path": "your-webhook-path",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "05de7a4a-03bf-4f60-9f6a-76317ab5a405",
      "name": "Process and Validate Data",
      "type": "n8n-nodes-base.code",
      "position": [
        816,
        576
      ],
      "parameters": {
        "jsCode": "// Data Validation & Enrichment\nconst body = $input.first().json.body || $input.first().json;\n\n// Validate required fields\nconst requiredFields = ['firmName', 'firmEmail', 'firmSize', 'primaryLocation', 'aiFrequency'];\nconst missingFields = requiredFields.filter(field => !body[field]);\n\nif (missingFields.length > 0) {\n  throw new Error('Missing required fields: ' + missingFields.join(', '));\n}\n\n// Normalize arrays (form builders may send single values as strings)\nconst normalizeArray = (val) => {\n  if (!val) return [];\n  if (Array.isArray(val)) return val;\n  return [val];\n};\n\n// Build enriched data object\nconst enrichedData = {\n  firmName: body.firmName.trim(),\n  firmContactName: (body.firmContactName || '').trim(),\n  firmEmail: body.firmEmail.trim().toLowerCase(),\n  firmSize: body.firmSize,\n  primaryLocation: body.primaryLocation.trim(),\n  practiceAreas: normalizeArray(body.practiceAreas),\n  jurisdictions: normalizeArray(body.jurisdictions),\n  otherJurisdictions: body.otherJurisdictions || '',\n  aiTools: normalizeArray(body.aiTools),\n  aiFrequency: body.aiFrequency,\n  aiUseCases: normalizeArray(body.aiUseCases),\n  dmsSystem: body.dmsSystem || 'Not specified',\n  mdmInUse: body.mdmInUse || 'Not specified',\n  dlpInUse: body.dlpInUse || 'Not specified',\n  usingPurview: body.usingPurview || 'Not specified',\n  sensitivityLabelsInUse: body.sensitivityLabelsInUse || 'Not specified',\n  complianceFrameworks: normalizeArray(body.complianceFrameworks),\n  copilotLicenseStatus: body.copilotLicenseStatus || 'Not specified',\n  m365LicenseTier: body.m365LicenseTier || 'Not specified',\n  clientDataConcerns: normalizeArray(body.clientDataConcerns),\n  existingAiPolicy: body.existingAiPolicy || 'Not specified',\n  additionalNotes: body.additionalNotes || '',\n  submittedAt: body.submittedAt || new Date().toISOString(),\n  reportDate: new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }),\n  reportId: 'AIGOV-' + Date.now().toString(36).toUpperCase()\n};\n\nconst allJurisdictions = [...enrichedData.jurisdictions];\nif (enrichedData.otherJurisdictions) {\n  allJurisdictions.push(...enrichedData.otherJurisdictions.split(',').map(j => j.trim()));\n}\n\nconst jurisdictionMap = {\n  'US Federal': ['federal AI regulation', 'NIST AI framework', 'FTC AI guidelines'],\n  'California': ['California AI law', 'CCPA AI', 'California Bar AI ethics'],\n  'New York': ['New York AI regulation', 'NY Bar AI ethics', 'NYC AI bias law'],\n  'Texas': ['Texas AI law', 'Texas Bar AI ethics', 'Texas data privacy'],\n  'European Union': ['EU AI Act', 'GDPR AI', 'European AI regulation'],\n  'United Kingdom': ['UK AI regulation', 'SRA AI guidance', 'UK data protection AI']\n};\n\nconst jurisdictionSearchTerms = [];\nallJurisdictions.forEach(j => {\n  if (jurisdictionMap[j]) {\n    jurisdictionSearchTerms.push(...jurisdictionMap[j]);\n  } else {\n    jurisdictionSearchTerms.push(j + ' AI regulation', j + ' legal AI ethics');\n  }\n});\n\nconst euAiActApplies = allJurisdictions.some(j =>\n  ['European Union', 'United Kingdom'].includes(j) ||\n  j.toLowerCase().includes('eu') || j.toLowerCase().includes('europe')\n);\n\nconst firmContext = [\n  'Firm: ' + enrichedData.firmName,\n  'Size: ' + enrichedData.firmSize,\n  'Primary Location: ' + enrichedData.primaryLocation,\n  'Practice Areas: ' + (enrichedData.practiceAreas.join(', ') || 'Not specified'),\n  'Jurisdictions: ' + allJurisdictions.join(', '),\n  'Current AI Tools: ' + (enrichedData.aiTools.join(', ') || 'None'),\n  'AI Usage Frequency: ' + enrichedData.aiFrequency,\n  'AI Use Cases: ' + (enrichedData.aiUseCases.join(', ') || 'Not specified'),\n  'Microsoft Copilot License Status: ' + enrichedData.copilotLicenseStatus,\n  'Microsoft 365 License Tier: ' + enrichedData.m365LicenseTier,\n  'DMS: ' + enrichedData.dmsSystem,\n  'MDM in Use: ' + enrichedData.mdmInUse,\n  'DLP in Use: ' + enrichedData.dlpInUse,\n  'Microsoft Purview: ' + enrichedData.usingPurview,\n  'Sensitivity Labels in Use: ' + enrichedData.sensitivityLabelsInUse,\n  'Compliance Frameworks: ' + (enrichedData.complianceFrameworks.join(', ') || 'None specified'),\n  'Existing AI Policy: ' + enrichedData.existingAiPolicy,\n  'Client Data Concerns: ' + (enrichedData.clientDataConcerns.join(', ') || 'None specified'),\n  'Additional Notes: ' + (enrichedData.additionalNotes || 'None')\n].join('\\n').trim();\n\nreturn [{ json: { ...enrichedData, allJurisdictions, jurisdictionSearchTerms, euAiActApplies, firmContext } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "bf4b1b97-9df0-4112-9f24-2aab2791577c",
      "name": "Respond via Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        976,
        576
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={\n  \"success\": true,\n  \"message\": \"Your AI Governance Policy documents are being generated. Our team will review them and send them to you shortly.\",\n  \"documentsGenerated\": [\n    \"Executive Summary (PDF)\",\n    \"Discussion & Brainstorming Guide (PDF)\",\n    \"Draft AI Governance Policy (PDF)\",\n    \"Implementation Plan & Next Steps (PDF)\"\n  ],\n  \"timestamp\": \"{{ $now.toISO() }}\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "b2878878-1525-4bbf-9d65-1da3a500bfd6",
      "name": "EU AI Act Research Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1232,
        -96
      ],
      "parameters": {
        "text": "=Research the EU AI Act and its implications for law firms.\n\nContext about the firm:\n{{ $json.firmContext }}\n\nSearch for and provide:\n1. Key EU AI Act requirements that apply to law firms using AI\n2. Risk classification requirements for legal AI tools\n3. Transparency and disclosure obligations\n4. Documentation and record-keeping requirements\n5. Prohibited AI practices relevant to legal services\n6. Timeline for compliance\n7. Penalties for non-compliance\n\nFocus on practical implications for a law firm of this size and practice areas. Include specific article references where relevant.\n\nProvide a structured summary with citations to official sources where possible.",
        "options": {
          "systemMessage": "You are a legal technology compliance expert specializing in the EU AI Act and its implications for legal services. Provide accurate, well-researched information with proper citations. Focus on actionable compliance guidance for law firms."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "7b329bda-0d33-49f9-816c-0955611a5a8a",
      "name": "OpenAI EU AI Act Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1232,
        80
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.3
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "19a6a45c-f45c-4af5-9160-b54f02c09630",
      "name": "Search EU AI Act",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        1376,
        80
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "0a6070a7-8ebf-4008-98bc-e3d23075d128",
      "name": "ABA Ethics Research Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1232,
        848
      ],
      "parameters": {
        "text": "=Research ABA (American Bar Association) ethics opinions and guidance related to AI use in legal practice.\n\nContext about the firm:\n{{ $json.firmContext }}\n\nSearch for and provide:\n1. ABA Formal Ethics Opinions on AI and technology use\n2. Model Rules of Professional Conduct implications for AI use\n3. Competence requirements (Rule 1.1) related to AI\n4. Confidentiality obligations (Rule 1.6) when using AI tools\n5. Supervision requirements for AI-assisted work\n6. Communication obligations to clients about AI use\n7. Recent state bar ethics opinions on AI (especially for jurisdictions: {{ $json.allJurisdictions.join(', ') }})\n\nInclude specific opinion numbers and dates where available. Focus on practical guidance for attorney compliance.",
        "options": {
          "systemMessage": "You are a legal ethics expert specializing in attorney professional responsibility and technology ethics. Provide accurate citations to ABA opinions, Model Rules, and state bar guidance. Focus on practical compliance guidance."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "19832e32-90b5-452c-bb78-7b30a6ca9184",
      "name": "OpenAI ABA Ethics Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1232,
        992
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.3
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "80d5e87a-9b88-4f5b-ba25-d8472b18d256",
      "name": "Search ABA Ethics",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        1376,
        992
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "15ebc7ad-d929-4172-b928-8299cbb1d150",
      "name": "Case Law Research Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1248,
        368
      ],
      "parameters": {
        "text": "=Research case law and sanctions related to AI misuse in legal practice.\n\nContext about the firm:\n{{ $json.firmContext }}\n\nSearch for and provide:\n1. Court cases involving AI-generated hallucinations or errors (e.g., Mata v. Avianca)\n2. Attorney sanctions for improper AI use\n3. Malpractice cases related to AI reliance\n4. Court rules and standing orders about AI disclosure\n5. Judicial guidance on AI use in litigation\n6. Cases involving AI and confidentiality breaches\n7. Recent developments in AI-related legal malpractice\n\nProvide case citations, court names, dates, and key holdings. Focus on lessons learned and risk mitigation strategies.",
        "options": {
          "systemMessage": "You are a legal research expert specializing in legal malpractice and attorney discipline cases. Provide accurate case citations and holdings. Focus on precedential value and practical risk mitigation guidance for law firms."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "ab0a518a-67f0-4c21-b25d-cbb5502e469d",
      "name": "OpenAI Case Law Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1248,
        544
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.3
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "19bcf818-7527-4f40-9950-dcb77060415e",
      "name": "Search Case Law",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        1392,
        544
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "cf4fab70-65e2-4bcf-8bce-8cebc572ba1b",
      "name": "Jurisdiction Regulations Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1248,
        1296
      ],
      "parameters": {
        "text": "=Research jurisdiction-specific AI regulations and guidance for the following jurisdictions:\n{{ $json.allJurisdictions.join(', ') }}\n\nContext about the firm:\n{{ $json.firmContext }}\n\nFor each relevant jurisdiction, search for and provide:\n1. State-specific AI legislation and regulations\n2. State bar ethics opinions on AI\n3. Data privacy laws affecting AI use (CCPA, state privacy laws)\n4. Consumer protection requirements\n5. Industry-specific regulations (healthcare, finance, etc.) relevant to practice areas\n6. Pending legislation that may affect AI use\n7. Local court rules regarding AI disclosure\n\nOrganize findings by jurisdiction. Include effective dates and compliance deadlines where applicable.",
        "options": {
          "systemMessage": "You are a regulatory compliance expert specializing in state and local AI regulations. Provide accurate, jurisdiction-specific guidance with proper citations to statutes, regulations, and bar opinions. Focus on practical compliance requirements."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "62a40628-d842-4670-80e5-1dfa513e619d",
      "name": "OpenAI Jurisdiction Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1248,
        1488
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.3
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "52f92206-0d7d-4161-945e-d166c3bf3f2e",
      "name": "Search Jurisdiction Laws",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        1392,
        1488
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "f6e77268-d92f-49ed-af15-dce5eda4f5e4",
      "name": "Combine Research Findings",
      "type": "n8n-nodes-base.merge",
      "position": [
        1632,
        272
      ],
      "parameters": {
        "numberInputs": 4
      },
      "typeVersion": 3.1
    },
    {
      "id": "7864f37c-559d-44ab-9a0a-0fd5e6609f09",
      "name": "Compile Research Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1824,
        304
      ],
      "parameters": {
        "jsCode": "// Aggregate all research results into a structured format using POSITIONAL indexing\n// Input order from Merge Research Results:\n//   index 0 = EU AI Act\n//   index 1 = ABA Ethics\n//   index 2 = Case Law & Sanctions\n//   index 3 = Jurisdiction Regulations\nconst items = $input.all();\n\n// Get firm data directly from the Validate node\nlet firmData = null;\ntry {\n  firmData = $('Process and Validate Data').first().json;\n} catch (e) {\n  firmData = {};\n}\n\n// Extract research outputs by POSITION (not content-sniffing)\nconst euAiActResearch = (items[0] && items[0].json) ? (items[0].json.output || '') : '';\nconst abaEthicsResearch = (items[1] && items[1].json) ? (items[1].json.output || '') : '';\nconst caseLawResearch = (items[2] && items[2].json) ? (items[2].json.output || '') : '';\nconst jurisdictionResearch = (items[3] && items[3].json) ? (items[3].json.output || '') : '';\n\nconst researchSummary = {\n  euAiAct: euAiActResearch || 'Research pending',\n  abaEthics: abaEthicsResearch || 'Research pending',\n  caseLaw: caseLawResearch || 'Research pending',\n  jurisdictionSpecific: jurisdictionResearch || 'Research pending'\n};\n\nconst combinedResearch = '## EU AI Act Research\\n' + researchSummary.euAiAct + '\\n\\n## ABA Ethics Research\\n' + researchSummary.abaEthics + '\\n\\n## Case Law & Sanctions\\n' + researchSummary.caseLaw + '\\n\\n## Jurisdiction-Specific Regulations\\n' + researchSummary.jurisdictionSpecific;\n\nreturn [{\n  json: {\n    ...firmData,\n    research: researchSummary,\n    combinedResearch,\n    generationTimestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6101237e-db0a-483b-a214-bde9a697662b",
      "name": "Executive Summary Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2080,
        -64
      ],
      "parameters": {
        "text": "=Create a comprehensive Executive Summary for an AI Governance Policy for the following law firm:\n\n{{ $json.firmContext }}\n\nBased on the following research:\n{{ $json.combinedResearch }}\n\nThe Executive Summary should include:\n\n1. **Purpose Statement**: Why this AI governance policy is essential for the firm\n\n2. **Scope Overview**: What AI tools and use cases are covered\n\n3. **Key Regulatory Drivers**: Summary of applicable regulations (EU AI Act, ABA ethics, state requirements)\n\n4. **Risk Assessment Highlights**: Primary risks identified for this firm's AI use\n\n5. **Core Policy Principles**: 4-6 guiding principles for AI use at the firm\n\n6. **Compliance Summary**: Key compliance requirements and deadlines\n\n7. **Recommended Immediate Actions**: Top 3-5 priority actions for the firm\n\nWrite in a professional tone suitable for law firm partners and management. Keep the summary to approximately 500-750 words. Use clear headings and concise language.",
        "options": {
          "systemMessage": "You are a legal technology policy expert who writes clear, professional executive summaries for law firm management. Your summaries are actionable, well-organized, and appropriate for partner-level audiences. Use professional legal writing style.\nCRITICAL: Output the content using HTML tags only. Do not use Markdown (e.g., no ### or |---|). Use <h2>, <h3>, <p>, <ul>, and especially <table>, <tr>, <td> for any structured data. Do not include <html> or <body> tags in your response, just the inner content."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "0f7164b4-2a15-4cc4-b50b-3245d9c4178a",
      "name": "OpenAI Summary Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2080,
        96
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.4
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4329dba8-b9cf-4ff7-a1ab-6ed05af5e4b1",
      "name": "Discussion Guide Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2080,
        912
      ],
      "parameters": {
        "text": "=Create a list of discussion topics for the initial AI Governance Policy planning meeting at:\n\n{{ $json.firmContext }}\n\nBased on the following research:\n{{ $json.combinedResearch }}\n\nCreate a structured brainstorming guide with the following sections:\n\n## 1. Strategic Questions for Leadership\n- 5-7 key questions about the firm's AI strategy\n- Focus on business objectives and competitive positioning\n\n## 2. Risk Assessment Topics\n- 6-8 specific risks to discuss\n- Include ethical, legal, reputational, and operational risks\n- Prioritize based on firm's practice areas and jurisdictions\n\n## 3. Use Case Evaluation\n- Review each current/planned AI use case\n- Questions to assess appropriateness and risk level\n- Criteria for approving new AI tools\n\n## 4. Client Considerations\n- Client disclosure requirements\n- Client consent processes\n- Managing client expectations\n\n## 5. Operational Questions\n- Training requirements\n- Supervision protocols\n- Quality control measures\n- Incident response planning\n\n## 6. Compliance Checklist Topics\n- Regulatory requirements to address\n- Documentation needs\n- Audit and monitoring processes\n\n## 7. Resource Allocation\n- Budget considerations\n- Staffing needs\n- Technology investments\n\nFormat as a facilitation guide that can be used to run a productive planning meeting. Include suggested time allocations for each section.",
        "options": {
          "systemMessage": "You are a legal technology consultant who facilitates AI governance planning sessions for law firms. Create practical, discussion-focused content that helps leadership teams have productive conversations about AI governance. Use clear formatting with actionable discussion questions.\nCRITICAL: Output the content using HTML tags only. Do not use Markdown (e.g., no ### or |---|). Use <h2>, <h3>, <p>, <ul>, and especially <table>, <tr>, <td> for any structured data. Do not include <html> or <body> tags in your response, just the inner content."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "098d7b24-8bf1-4b87-ae5e-82456544b9c5",
      "name": "OpenAI Discussion Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2080,
        1056
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.5
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "13a3d4dd-4dd9-4240-b008-f1497d2102bd",
      "name": "Draft Policy Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2080,
        416
      ],
      "parameters": {
        "text": "=Draft a comprehensive AI Governance Policy for:\n\n{{ $json.firmContext }}\n\nBased on the following research:\n{{ $json.combinedResearch }}\n\nCreate a complete, professional policy document with the following structure:\n\n## POLICY DOCUMENT STRUCTURE\n\n### 1. INTRODUCTION\n- Policy purpose and objectives\n- Scope and applicability\n- Definitions of key terms\n- Effective date and review schedule\n\n### 2. GUIDING PRINCIPLES\n- Ethical AI use principles\n- Client-first commitment\n- Professional responsibility alignment\n- Transparency and accountability\n\n### 3. APPROVED AI TOOLS AND USES\n- Categories of approved AI tools\n- Approved use cases by practice area\n- Prohibited uses\n- Tool evaluation and approval process\n\n### 4. DATA SECURITY AND CONFIDENTIALITY\n- Client data protection requirements\n- Prohibited data inputs to AI systems\n- Data classification guidelines\n- Vendor security requirements\n\n### 5. QUALITY CONTROL AND VERIFICATION\n- Mandatory human review requirements\n- Verification procedures for AI outputs\n- Documentation standards\n- Error reporting and correction\n\n### 6. CLIENT DISCLOSURE AND CONSENT\n- Disclosure requirements by matter type\n- Consent procedures\n- Engagement letter language\n- Client communication templates\n\n### 7. TRAINING AND COMPETENCE\n- Mandatory training requirements\n- Competence verification\n- Ongoing education\n- New attorney onboarding\n\n### 8. SUPERVISION AND ACCOUNTABILITY\n- Supervisory responsibilities\n- Partner oversight requirements\n- Associate and staff guidelines\n- Accountability framework\n\n### 9. COMPLIANCE AND MONITORING\n- Compliance verification procedures\n- Audit requirements\n- Reporting obligations\n- Record retention\n\n### 10. INCIDENT RESPONSE\n- Incident identification and reporting\n- Response procedures\n- Client notification requirements\n- Remediation steps\n\n### 11. POLICY GOVERNANCE\n- Policy ownership\n- Amendment procedures\n- Exception requests\n- Annual review process\n\n### APPENDICES\n- Appendix A: Approved AI Tools List\n- Appendix B: AI Use Request Form\n- Appendix C: Client Disclosure Templates\n- Appendix D: Training Acknowledgment Form\n\nWrite the policy in formal legal language appropriate for a law firm policy document. Include specific references to applicable rules and regulations identified in the research. Make the policy comprehensive but practical for implementation.",
        "options": {
          "systemMessage": "You are a legal policy drafting expert who creates comprehensive governance policies for law firms. Write in formal legal policy language with clear, enforceable provisions. Include specific regulatory citations where appropriate. Create practical, implementable policies that balance compliance requirements with operational efficiency.\nCRITICAL: Output the content using HTML tags only. Do not use Markdown (e.g., no ### or |---|). Use <h2>, <h3>, <p>, <ul>, and especially <table>, <tr>, <td> for any structured data. Do not include <html> or <body> tags in your response, just the inner content."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "e86a9734-1bbe-46c4-9252-1165eb0d1156",
      "name": "OpenAI Policy Drafting",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2080,
        576
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {
          "temperature": 0.4
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3ab89ecd-ec06-4c21-bcfb-8dd79398d3ee",
      "name": "Roadmap Development Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2080,
        1408
      ],
      "parameters": {
        "text": "=Create a detailed Next Steps and Implementation Plan for AI Governance at:\n\n{{ $json.firmContext }}\n\nBased on the following research:\n{{ $json.combinedResearch }}\n\nCreate an actionable implementation roadmap with:\n\n## IMMEDIATE ACTIONS (Next 30 Days)\n- Critical compliance steps\n- Quick wins to implement immediately\n- Risk mitigation priorities\n- Specific tasks with responsible parties\n\n## SHORT-TERM IMPLEMENTATION (30-90 Days)\n- Policy finalization and approval process\n- Training program development\n- Tool assessment and approval\n- Client communication rollout\n- Documentation system setup\n\n## MEDIUM-TERM GOALS (90-180 Days)\n- Full policy implementation\n- Training completion milestones\n- Monitoring system implementation\n- First compliance audit\n- Policy refinement based on feedback\n\n## LONG-TERM OBJECTIVES (6-12 Months)\n- Mature governance program\n- Advanced AI use case expansion\n- Industry benchmarking\n- Continuous improvement processes\n\n## RESOURCE REQUIREMENTS\n- Personnel needs\n- Budget estimates\n- Technology investments\n- External expertise (if needed)\n\n## KEY MILESTONES AND DEADLINES\n- Compliance deadlines (regulatory)\n- Internal milestones\n- Review dates\n- Reporting requirements\n\n## SUCCESS METRICS\n- KPIs for AI governance program\n- Compliance metrics\n- Training completion rates\n- Incident tracking\n\n## RECOMMENDED NEXT MEETING AGENDA\n- Topics to address in follow-up session\n- Decisions needed from leadership\n- Information to gather\n\nFormat as an actionable project plan that the firm can begin executing immediately.",
        "options": {
          "systemMessage": "You are a legal technology implementation consultant who creates practical, actionable implementation plans for law firms. Create specific, measurable action items with clear timelines and responsibilities. Focus on practical steps that a law firm can realistically accomplish.\nCRITICAL: Output the content using HTML tags only. Do not use Markdown (e.g., no ### or |---|). Use <h2>, <h3>, <p>, <ul>, and especially <table>, <tr>, <td> for any structured data. Do not include <html> or <body> tags in your response, just the inner content."
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "558cd69e-482a-4f15-b9e3-3b2b01319417",
      "name": "OpenAI Roadmap Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2080,
        1568
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {
          "temperature": 0.4
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c8c66b04-04ee-43cf-bf3c-626d6ad3f82c",
      "name": "Combine Generated Outputs",
      "type": "n8n-nodes-base.merge",
      "position": [
        2480,
        240
      ],
      "parameters": {
        "numberInputs": 4
      },
      "typeVersion": 3.1
    },
    {
      "id": "c75d8b82-bc12-4566-b5ab-2fdf9191117d",
      "name": "Create Branded HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        2624,
        272
      ],
      "parameters": {
        "jsCode": "// Compile generated outputs using POSITIONAL indexing, apply branded HTML\nconst items = $input.all();\nconst firmData = $('Compile Research Data').first().json;\n\n// Extract content by POSITION\nconst executiveSummary = (items[0] && items[0].json) ? (items[0].json.output || '') : '';\nconst brainstormingTopics = (items[1] && items[1].json) ? (items[1].json.output || '') : '';\nconst draftPolicy = (items[2] && items[2].json) ? (items[2].json.output || '') : '';\nconst nextSteps = (items[3] && items[3].json) ? (items[3].json.output || '') : '';\n\nconst reportDate = firmData.reportDate || new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\nconst reportId = firmData.reportId || 'AIGOV-' + Date.now().toString(36).toUpperCase();\nconst firmName = firmData.firmName || 'Client Firm';\nconst firmEmail = firmData.firmEmail || '';\nconst firmContactName = firmData.firmContactName || '';\nconst logoUrl = 'YOUR_LOGO_URL';\n\nfunction processContent(content) {\n  if (!content) return '<p>Content not available</p>';\n  const containsHtml = /<[a-z][\\s\\S]*>/i.test(content);\n  if (containsHtml) return content.trim();\n  let html = content\n    .replace(/^### (.+)$/gm, '<h3>$1</h3>')\n    .replace(/^## (.+)$/gm, '<h2>$1</h2>')\n    .replace(/^# (.+)$/gm, '<h1>$1</h1>')\n    .replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>')\n    .replace(/^- (.+)$/gm, '<li>$1</li>')\n    .replace(/\\n\\n/g, '</p><p>')\n    .replace(/\\n/g, '<br>');\n  html = html.replace(/(<li>.*<\\/li>)/gs, '<ul>$1</ul>').replace(/<\\/ul><ul>/g, '');\n  return html;\n}\n\nconst createHtmlDoc = (subtitle, content, isDraft) => {\n  isDraft = isDraft || false;\n  return '<!DOCTYPE html>\\n<html lang=\"en\">\\n<head>\\n  <meta charset=\"UTF-8\">\\n  <style>\\n    :root { --navy: #002657; --blue: #0021a5; --orange: #fa4616; --charcoal: #343741; }\\n    @page { size: letter; margin: 0.75in; }\\n    body { font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif; line-height: 1.5; color: var(--charcoal); padding: 0; margin: 0; font-size: 11pt; }\\n    .header { display: flex; justify-content: space-between; align-items: center; border-bottom: 4px solid var(--orange); padding-bottom: 15px; margin-bottom: 25px; }\\n    .logo { height: 60px; }\\n    .header-text { text-align: right; }\\n    .header-text h1 { color: var(--navy); font-size: 20px; margin: 0; text-transform: uppercase; }\\n    .header-text p { color: var(--blue); font-size: 12px; margin: 4px 0 0 0; font-weight: bold; }\\n    .meta { font-size: 9px; color: #999; margin-top: 5px; }\\n    ' + (isDraft ? '.draft-banner { background: #fff5f2; color: var(--orange); padding: 10px; text-align: center; font-weight: bold; border: 1px solid var(--orange); margin-bottom: 20px; border-radius: 4px; }' : '') + '\\n    h1 { color: var(--navy); font-size: 18px; border-bottom: 1px solid #eee; padding-bottom: 5px; }\\n    h2 { color: var(--navy); border-left: 4px solid var(--blue); padding-left: 10px; font-size: 15px; margin-top: 20px; }\\n    h3 { color: var(--blue); font-size: 13px; }\\n    ul { padding-left: 20px; }\\n    li { margin: 6px 0; }\\n    table { width: 100%; border-collapse: collapse; margin: 20px 0; }\\n    th { background-color: var(--navy); color: white; text-align: left; padding: 10px; font-size: 10pt; }\\n    td { border: 1px solid #eee; padding: 8px; vertical-align: top; font-size: 10pt; }\\n    tr:nth-child(even) { background-color: #f9f9f9; }\\n    .footer { border-top: 1px solid #eee; margin-top: 30px; padding-top: 15px; text-align: center; color: #999; font-size: 9px; }\\n  </style>\\n</head>\\n<body>\\n  <div class=\"header\">\\n    <img src=\"' + logoUrl + '\" class=\"logo\">\\n    <div class=\"header-text\">\\n      <h1>AI Governance Policy</h1>\\n      <p>' + subtitle + '</p>\\n      <div class=\"meta\">ID: ' + reportId + ' | ' + reportDate + '</div>\\n    </div>\\n  </div>\\n  ' + (isDraft ? '<div class=\"draft-banner\">CONFIDENTIAL DRAFT: INTERNAL REVIEW ONLY</div>' : '') + '\\n  <div class=\"content\">' + processContent(content) + '</div>\\n  <div class=\"footer\">\\n    <p>Prepared for ' + firmName + '</p>\\n  </div>\\n</body>\\n</html>';\n};\n\nconst docs = [\n  { sub: 'Executive Summary', cont: executiveSummary, draft: false },\n  { sub: 'Strategic Discussion Guide', cont: brainstormingTopics, draft: false },\n  { sub: 'Draft Policy Framework', cont: draftPolicy, draft: true },\n  { sub: 'Implementation Roadmap', cont: nextSteps, draft: false }\n];\n\nconst dateStr = new Date().toISOString().split('T')[0];\nconst safeName = firmName.replace(/[^a-zA-Z0-9]/g, '_');\n\nreturn docs.map((doc, i) => {\n  const html = createHtmlDoc(doc.sub, doc.cont, doc.draft);\n  return {\n    json: {\n      fileName: safeName + '_' + doc.sub.replace(/\\s+/g, '_') + '_' + dateStr + '.pdf',\n      docTitle: doc.sub,\n      firmName: firmName,\n      firmEmail: firmEmail,\n      firmContactName: firmContactName,\n      reportId: reportId,\n      reportDate: reportDate,\n      docIndex: i\n    },\n    binary: {\n      data: {\n        data: Buffer.from(html, 'utf-8').toString('base64'),\n        mimeType: 'text/html',\n        fileName: 'index.html'\n      }\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "a5d43dbd-a4e7-4226-9f4c-f3049e8c57b5",
      "name": "Convert HTML to PDF",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2800,
        272
      ],
      "parameters": {
        "url": "https://YOUR_GOTENBERG_HOST/forms/chromium/convert/html",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "index1.html",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "=data"
            }
          ]
        },
        "genericAuthType": "httpBasicAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Gotenberg-Output-Filename",
              "value": "={{ $json.fileName }}"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "82bcd886-9b16-4fbd-a04f-a8c204f9407d",
      "name": "Upload PDF to SharePoint",
      "type": "n8n-nodes-base.microsoftSharePoint",
      "position": [
        2992,
        272
      ],
      "parameters": {
        "site": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SHAREPOINT_SITE_ID",
          "cachedResultName": "YOUR_SITE_NAME"
        },
        "folder": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_FOLDER_ID",
          "cachedResultName": "Policy Documents"
        },
        "fileName": "={{ $json.fileName }}",
        "operation": "upload",
        "fileContents": "data",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "50f4af97-cf48-4186-ae6e-2713f4fa6e6f",
      "name": "Generate Share Links",
      "type": "n8n-nodes-base.code",
      "position": [
        3152,
        272
      ],
      "parameters": {
        "jsCode": "// Build SharePoint share links from upload responses\nconst items = $input.all();\nconst compileItems = $('Create Branded HTML').all();\n\nreturn items.map((item, index) => {\n  const shareLink = item.json.webUrl || '';\n  const upstream = compileItems[index] ? compileItems[index].json : {};\n  return {\n    json: {\n      fileName: upstream.fileName || item.json.name || '',\n      docTitle: upstream.docTitle || '',\n      docIndex: upstream.docIndex ?? index,\n      shareLink,\n      firmName: upstream.firmName || '',\n      firmEmail: upstream.firmEmail || '',\n      firmContactName: upstream.firmContactName || '',\n      reportId: upstream.reportId || '',\n      reportDate: upstream.reportDate || ''\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "024dc629-e6c1-47d4-898d-d36f9e02f386",
      "name": "Collect SharePoint Links",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3328,
        272
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "0c61c319-417b-4d27-b4c5-0dbde66bf047",
      "name": "Draft Review Email",
      "type": "n8n-nodes-base.code",
      "position": [
        3520,
        272
      ],
      "parameters": {
        "jsCode": "// Prepare internal review email with SharePoint links and draft forward message\nconst allData = $input.first().json;\nconst items = allData.data || [allData];\nconst firstItem = Array.isArray(items) ? items[0] : items;\n\nconst firmName = firstItem.firmName || 'Client Firm';\nconst firmEmail = firstItem.firmEmail || '';\nconst firmContactName = firstItem.firmContactName || '';\nconst reportId = firstItem.reportId || '';\nconst reportDate = firstItem.reportDate || '';\n\nconst docLinks = [];\nif (Array.isArray(items)) {\n  const sorted = [...items].sort((a, b) => (a.docIndex || 0) - (b.docIndex || 0));\n  sorted.forEach(item => {\n    docLinks.push({\n      title: item.docTitle || item.fileName,\n      link: item.shareLink || '#'\n    });\n  });\n}\n\nlet linksHtml = '';\ndocLinks.forEach((doc, i) => {\n  linksHtml += '<li style=\"margin: 8px 0;\"><strong>' + doc.title + '</strong><br><a href=\"' + doc.link + '\" style=\"color: #0021A5; text-decoration: underline;\">' + doc.link + '</a></li>';\n});\n\nconst contactGreeting = firmContactName ? ('Dear ' + firmContactName) : ('Dear ' + firmName + ' Team');\nconst draftForwardMessage = '<div style=\"background: #f7fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 20px; margin: 20px 0;\">'\n  + '<h3 style=\"color: #002657; margin: 0 0 10px 0; font-size: 15px;\">DRAFT MESSAGE TO FORWARD TO REQUESTOR</h3>'\n  + '<p style=\"font-size: 12px; color: #666; margin-bottom: 12px;\"><em>Copy the text below into a new email to the requestor after reviewing all documents.</em></p>'\n  + '<div style=\"background: #ffffff; border: 1px dashed #ccc; border-radius: 6px; padding: 16px; font-size: 13px; line-height: 1.6; color: #333;\">'\n  + '<p>' + contactGreeting + ',</p>'\n  + '<p>Thank you for requesting an AI Governance Policy. Your customized documents are complete and ready for your review.</p>'\n  + '<p><strong>Your documents:</strong></p>'\n  + '<ol>' + docLinks.map(d => '<li><strong>' + d.title + '</strong></li>').join('') + '</ol>'\n  + '<p>Please note:</p>'\n  + '<ul>'\n  + '<li>The Draft Policy is a starting point and should be reviewed and customized by your firm\\'s leadership</li>'\n  + '<li>We recommend legal review before formal adoption of any policy</li>'\n  + '<li>Regulatory requirements continue to evolve \ufffd periodic review is recommended</li>'\n  + '</ul>'\n  + '<p>If you have questions or would like assistance with implementation, please reach out.</p>'\n  + '</div>'\n  + '</div>';\n\nconst emailBody = '<div style=\"font-family: Segoe UI, Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; max-width: 650px;\">'\n  + '<div style=\"background: #002657; color: #ffffff; padding: 16px 20px; border-radius: 8px 8px 0 0;\">'\n  + '<h2 style=\"margin: 0; font-size: 18px; color: #ffffff;\">Internal Review Required \ufffd AI Governance Documents</h2>'\n  + '</div>'\n  + '<div style=\"border: 1px solid #e2e8f0; border-top: none; border-radius: 0 0 8px 8px; padding: 20px;\">'\n  + '<p>New AI Governance Policy documents have been generated and require your review before delivery.</p>'\n  + '<div style=\"background: #fffaf0; border-left: 4px solid #FA4616; padding: 12px 16px; margin: 16px 0;\">'\n  + '<h3 style=\"color: #FA4616; margin: 0 0 8px 0; font-size: 14px;\">REQUESTOR INFORMATION</h3>'\n  + '<table style=\"font-size: 13px; border-collapse: collapse;\">'\n  + '<tr><td style=\"padding: 3px 12px 3px 0; color: #666; font-weight: bold;\">Firm:</td><td>' + firmName + '</td></tr>'\n  + '<tr><td style=\"padding: 3px 12px 3px 0; color: #666; font-weight: bold;\">Contact:</td><td>' + (firmContactName || 'Not provided') + '</td></tr>'\n  + '<tr><td style=\"padding: 3px 12px 3px 0; color: #666; font-weight: bold;\">Email:</td><td>' + firmEmail + '</td></tr>'\n  + '<tr><td style=\"padding: 3px 12px 3px 0; color: #666; font-weight: bold;\">Report ID:</td><td>' + reportId + '</td></tr>'\n  + '<tr><td style=\"padding: 3px 12px 3px 0; color: #666; font-weight: bold;\">Generated:</td><td>' + reportDate + '</td></tr>'\n  + '</table>'\n  + '</div>'\n  + '<div style=\"background: #ebf8ff; border-left: 4px solid #0021A5; padding: 12px 16px; margin: 16px 0;\">'\n  + '<h3 style=\"color: #0021A5; margin: 0 0 8px 0; font-size: 14px;\">GENERATED DOCUMENTS (SharePoint)</h3>'\n  + '<ol style=\"margin: 8px 0; padding-left: 20px;\">' + linksHtml + '</ol>'\n  + '</div>'\n  + draftForwardMessage\n  + '</div>'\n  + '</div>';\n\nreturn [{ json: { emailBody, firmName, reportId } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "63afca65-af22-4f8c-b0be-e800ccd23b1e",
      "name": "Send Review Email",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        3680,
        272
      ],
      "parameters": {
        "subject": "=[REVIEW] AI Governance Documents - {{ $json.firmName }} ({{ $json.reportId }})",
        "bodyContent": "={{ $json.emailBody }}",
        "toRecipients": "user@example.com",
        "additionalFields": {}
      },
      "typeVersion": 2
    },
    {
      "id": "339fb181-98e8-4c1f-aacf-0b8ae37b5d1b",
      "name": "Sticky \u2014 Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        80
      ],
      "parameters": {
        "width": 500,
        "height": 1000,
        "content": "### AI Governance Policy Generator\n\nDesigned for legal technology consultants and law firms who need a research-backed, customized AI governance policy package. A webhook intake form triggers the workflow; four parallel AI research agents gather current intelligence, and four parallel generation agents produce four professional PDF documents delivered to SharePoint.\n\n### How it works\n1. A POST request arrives from a website intake form (Webhook trigger)\n2. **Validate & Enrich** parses and normalizes the form fields\n3. An **immediate JSON response** is returned to the browser\n4. Four **Research Agents** run in parallel using GPT-4.1 + SerpAPI: EU AI Act, ABA Ethics, Case Law & Sanctions, and Jurisdiction-Specific Regulations\n5. Research is **merged and aggregated** into a unified context object\n6. Four **Generation Agents** produce: Executive Summary, Discussion Guide, Draft Policy Framework, and Implementation Roadmap as HTML\n7. **Compile Outputs** wraps each document in branded HTML\n8. Documents are **converted to PDF** via Gotenberg and **uploaded to SharePoint**\n9. An **internal review email** is sent via Outlook with SharePoint links and a pre-drafted forwarding message\n\n### Setup\n1. Add credentials: **OpenAI**, **SerpAPI**, **Microsoft SharePoint**, **Microsoft Outlook**, and **Gotenberg Basic Auth**\n2. Install the `n8n-nodes-serpapi` community node (Settings \u2192 Community Nodes)\n3. Update the SharePoint **site ID** and **folder ID** in the `SharePoint \u2014 Upload PDF` node\n4. Update the **recipient email address(es)** in the `Outlook \u2014 Send Review Email` node\n5. Verify the **Gotenberg URL** in the `HTTP \u2014 Convert HTML to PDF` node\n6. Configure the webhook path to match your intake form endpoint\n\n### Customization\n- Swap SerpAPI for **Tavily** (`@n8n/n8n-nodes-langchain.toolTavily`) for AI-optimized search without a community node\n- Add or remove research agent branches to expand or narrow research scope\n- Update HTML branding in **Code \u2014 Compile Branded HTML** to match your organization\n\nSupport: support@legalgpts.com\nhttps://automatedintelligentsolutions.com"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "5f43235a-9216-495e-af7b-372c7faa79c0",
  "connections": {
    "Search Case Law": {
      "ai_tool": [
        [
          {
            "node": "Case Law Research Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Search EU AI Act": {
      "ai_tool": [
        [
          {
            "node": "EU AI Act Research Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Search ABA Ethics": {
      "ai_tool": [
        [
          {
            "node": "ABA Ethics Research Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Draft Policy Agent": {
      "main": [
        [
          {
            "node": "Combine Generated Outputs",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Draft Review Email": {
      "main": [
        [
          {
            "node": "Send Review Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert HTML to PDF": {
      "main": [
        [
          {
            "node": "Upload PDF to SharePoint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Branded HTML": {
      "main": [
        [
          {
            "node": "Convert HTML to PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond via Webhook": {
      "main": [
        [
          {
            "node": "EU AI Act Research Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "ABA Ethics Research Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Case Law Research Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Jurisdiction Regulations Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Form Submitted": {
      "main": [
        [
          {
            "node": "Process and Validate Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Share Links": {
      "main": [
        [
          {
            "node": "Collect SharePoint Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compile Research Data": {
      "main": [
        [
          {
            "node": "Executive Summary Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Discussion Guide Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Draft Policy Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Roadmap Development Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Discussion Guide Agent": {
      "main": [
        [
          {
            "node": "Combine Generated Outputs",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "OpenAI Policy Drafting": {
      "ai_languageModel": [
        [
          {
            "node": "Draft Policy Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Case Law Research Agent": {
      "main": [
        [
          {
            "node": "Combine Research Findings",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Executive Summary Agent": {
      "main": [
        [
          {
            "node": "Combine Generated Outputs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Roadmap Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Roadmap Development Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Summary Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Executive Summary Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Collect SharePoint Links": {
      "main": [
        [
          {
            "node": "Draft Review Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "EU AI Act Research Agent": {
      "main": [
        [
          {
            "node": "Combine Research Findings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Case Law Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Case Law Research Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Search Jurisdiction Laws": {
      "ai_tool": [
        [
          {
            "node": "Jurisdiction Regulations Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Upload PDF to SharePoint": {
      "main": [
        [
          {
            "node": "Generate Share Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ABA Ethics Research Agent": {
      "main": [
        [
          {
            "node": "Combine Research Findings",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Combine Generated Outputs": {
      "main": [
        [
          {
            "node": "Create Branded HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Research Findings": {
      "main": [
        [
          {
            "node": "Compile Research Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI EU AI Act Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "EU AI Act Research Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Process and Validate Data": {
      "main": [
        [
          {
            "node": "Respond via Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Roadmap Development Agent": {
      "main": [
        [
          {
            "node": "Combine Generated Outputs",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "OpenAI ABA Ethics Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "ABA Ethics Research Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Discussion Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Discussion Guide Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Jurisdiction Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Jurisdiction Regulations Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Jurisdiction Regulations Agent": {
      "main": [
        [
          {
            "node": "Combine Research Findings",
            "type": "main",
            "index": 3
          }
        ]
      ]
    }
  }
}