{
  "name": "Complaint Triage Orchestrator (S2.3)",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000001",
      "name": "Schedule Trigger (15 min)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -400,
        -100
      ]
    },
    {
      "parameters": {},
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000002",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -400,
        100
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// Watermark-based fetch (spec Section 5) -- read the last date_received we\n// successfully advanced past, or fall back to an initial lookback window on\n// the very first run.\n//\n// Why a lookback window and not \"since yesterday\": the CFPB Consumer Complaint\n// Database only publishes a complaint once the company has responded or 15\n// calendar days have passed (spec Section 3b, the CFPB 15-day rule). A poll\n// watermarked to \"yesterday\" would mostly return nothing. INITIAL_LOOKBACK_DAYS\n// gives the first run a realistic chance of hits while still behaving like a\n// genuine incremental poller from the second run onward.\nconst INITIAL_LOOKBACK_DAYS = 30;\n\nconst staticData = $getWorkflowStaticData('global');\n\nlet watermarkDate = staticData.lastWatermarkDate;\nlet isFirstRun = false;\n\nif (!watermarkDate) {\n  isFirstRun = true;\n  const fallback = new Date();\n  fallback.setUTCDate(fallback.getUTCDate() - INITIAL_LOOKBACK_DAYS);\n  watermarkDate = fallback.toISOString().slice(0, 10); // YYYY-MM-DD\n}\n\nreturn [\n  {\n    json: {\n      watermarkDate,\n      isFirstRun,\n    },\n  },\n];\n"
      },
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000003",
      "name": "Get Watermark",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -160,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://www.consumerfinance.gov/data-research/consumer-complaints/search/api/v1/",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "product",
              "value": "Debt collection"
            },
            {
              "name": "product",
              "value": "Credit card"
            },
            {
              "name": "date_received_min",
              "value": "={{ $json.watermarkDate }}"
            },
            {
              "name": "size",
              "value": "25"
            },
            {
              "name": "sort",
              "value": "created_date_asc"
            },
            {
              "name": "no_aggs",
              "value": "true"
            }
          ]
        },
        "options": {}
      },
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000004",
      "name": "CFPB Complaint Search",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        60,
        0
      ],
      "notesInFlow": true,
      "notes": "Pilot scope (spec Section 4): Debt collection + Credit card only. product= repeated as two query params is a real, verified OR filter against the live API (confirmed by build-time testing, not assumed from docs). date_received_min accepts YYYY-MM-DD only -- the live API rejects sub-day timestamps, confirmed by testing during Phase 1 build."
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// Cap to 25/run (spec Section 5 -- cost predictability, not a rate-limit\n// necessity; size=25 is already set on the request, this is a defensive\n// second cap), flatten each ES hit down to the fields the rest of the\n// pipeline needs (spec Section 3a), and advance the watermark to the latest\n// date_received actually seen in this batch.\n//\n// Watermark precision note: CFPB's date_received_min filter is date-level\n// (YYYY-MM-DD), not timestamp-level -- confirmed live during Phase 1 build\n// (a sub-day timestamp is rejected by the API). That means a same-day poll\n// can re-return complaints already fetched earlier that day. This workflow\n// does not dedup here by design -- spec Section 11 assigns dedup to the\n// storage layer (\"Google Sheets Append-or-Update, dedup via complaint ID\"),\n// wired in a later phase. Downstream nodes must not assume every item here\n// is new.\nconst MAX_PER_RUN = 25;\n\nconst response = $input.first().json;\nconst hits = (response.hits && response.hits.hits) || [];\nconst capped = hits.slice(0, MAX_PER_RUN);\n\nconst staticData = $getWorkflowStaticData('global');\nlet maxDate = staticData.lastWatermarkDate || null;\n\nconst out = capped.map((hit) => {\n  const src = hit._source;\n  const received = (src.date_received || '').slice(0, 10);\n  if (received && (!maxDate || received > maxDate)) {\n    maxDate = received;\n  }\n  return {\n    json: {\n      complaint_id: src.complaint_id,\n      product: src.product,\n      sub_product: src.sub_product,\n      issue: src.issue,\n      sub_issue: src.sub_issue,\n      company: src.company,\n      state: src.state,\n      tags: src.tags,\n      date_received: src.date_received,\n      timely: src.timely,\n      company_response: src.company_response,\n      complaint_what_happened: src.complaint_what_happened,\n    },\n  };\n});\n\nif (maxDate) {\n  staticData.lastWatermarkDate = maxDate;\n}\n\nreturn out;\n"
      },
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000005",
      "name": "Cap Batch & Advance Watermark",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        280,
        0
      ],
      "notesInFlow": true,
      "notes": "End of Phase 1: capped, flattened batch of new-since-watermark tickets."
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// Synthetic customer/account record generator (spec Section 3c).\n//\n// Structured like a real bank CRM export -- tenure, tier, holdings, balance,\n// contact history -- but every field is synthetic EXCEPT linked_complaint_id\n// (the real CFPB complaint ID) and the two flags below, which carry forward\n// CFPB's own real `tags` field where it exists. That carry-forward is the\n// deliberately-real part of an otherwise-synthetic record (spec Section 12) --\n// never blur it with the rest, and never let this record be mistaken for a\n// real CRM export in any downstream dashboard/report (Section 14).\n//\n// Deterministic, not random-per-run: seeded from complaint_id (mulberry32 PRNG)\n// so re-processing the same ticket -- a retry, a re-run, a dedup pass hitting\n// the same complaint_id twice because of the date-level watermark overlap\n// noted upstream -- always yields the same synthetic record instead of a new\n// random one each time.\n\nfunction mulberry32(seed) {\n  return function () {\n    seed |= 0; seed = (seed + 0x6D2B79F5) | 0;\n    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);\n    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n  };\n}\n\nfunction seedFromString(str) {\n  let h = 2166136261;\n  for (let i = 0; i < str.length; i++) {\n    h ^= str.charCodeAt(i);\n    h = Math.imul(h, 16777619);\n  }\n  return h >>> 0;\n}\n\nfunction weightedPick(rng, weighted) {\n  const total = weighted.reduce((s, [, w]) => s + w, 0);\n  let r = rng() * total;\n  for (const [value, weight] of weighted) {\n    if (r < weight) return value;\n    r -= weight;\n  }\n  return weighted[weighted.length - 1][0];\n}\n\nconst PRODUCT_POOL = [\n  'Checking Account', 'Savings Account', 'Credit Card', 'Personal Loan',\n  'Auto Loan', 'Mortgage', 'Home Equity Line of Credit', 'Certificate of Deposit',\n];\n\nconst items = $input.all();\n\nconst out = items.map((item) => {\n  const ticket = item.json;\n  const rng = mulberry32(seedFromString(String(ticket.complaint_id)));\n\n  const tenure_years = weightedPick(rng, [[0,3],[1,4],[2,4],[3,4],[4,3],[5,3],[6,2],[7,2],[8,1],[9,1],[10,1],[12,1],[15,1]]);\n  const received = new Date(ticket.date_received);\n  const since = new Date(received);\n  since.setUTCFullYear(since.getUTCFullYear() - tenure_years);\n  since.setUTCMonth(Math.floor(rng() * 12));\n  since.setUTCDate(1 + Math.floor(rng() * 28));\n  const customer_since = since.toISOString().slice(0, 10);\n\n  const account_tier = weightedPick(rng, [['Standard', 7], ['Preferred', 2], ['Premier', 1]]);\n\n  const holdingsCount = weightedPick(rng, [[1, 5], [2, 3], [3, 1], [4, 1]]);\n  const shuffled = [...PRODUCT_POOL].sort(() => rng() - 0.5);\n  const product_holdings = shuffled.slice(0, holdingsCount);\n\n  const outstanding_balance_usd = weightedPick(rng, [[0, 3], [1, 1]]) === 0\n    ? 0\n    : Math.round(rng() * 15000 * 100) / 100;\n\n  const prior_complaints_12mo = weightedPick(rng, [[0, 6], [1, 2], [2, 1], [3, 1]]);\n  const prior_contacts_90d = weightedPick(rng, [[0, 4], [1, 3], [2, 2], [3, 1], [4, 1]]);\n  const preferred_channel = weightedPick(rng, [['Web', 5], ['Phone', 3], ['Mail', 1]]);\n\n  // Real-tag carry-forward (spec Section 3c/12). CFPB's own `tags` field is\n  // real government data, not synthetic. Values seen in the wild: null,\n  // \"Servicemember\", \"Older American\", or \"Older American, Servicemember\".\n  // special_population_flag is the broader of the two -- CFPB itself treats\n  // servicemembers and older Americans together as populations warranting\n  // extra-care handling, so a Servicemember tag sets both flags true.\n  const tags = ticket.tags || '';\n  const servicemember_flag = tags.includes('Servicemember');\n  const special_population_flag = tags.includes('Servicemember') || tags.includes('Older American');\n\n  return {\n    json: {\n      ...ticket,\n      crm: {\n        account_id: `SYN-${seedFromString(String(ticket.complaint_id)).toString(36).toUpperCase()}`,\n        linked_complaint_id: String(ticket.complaint_id),\n        customer_since,\n        tenure_years,\n        account_tier,\n        product_holdings,\n        outstanding_balance_usd,\n        prior_complaints_12mo,\n        prior_contacts_90d,\n        preferred_channel,\n        servicemember_flag,\n        special_population_flag,\n      },\n    },\n  };\n});\n\nreturn out;\n"
      },
      "id": "a1e6c2f0-1a2b-4c3d-8e4f-000000000006",
      "name": "Generate Synthetic CRM Record",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        500,
        0
      ],
      "notesInFlow": true,
      "notes": "Phase 2. Adds a synthetic CRM record (spec Section 3c) per ticket under `crm`. Only linked_complaint_id, servicemember_flag, and special_population_flag are real/hybrid -- everything else in `crm` is synthetic (Section 12) and must be labelled as such wherever it surfaces downstream (dashboard, README -- Section 14). End of Phase 2: agents, escalation gate, and storage/dedup are not yet wired."
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "// Fixture test path (spec Section 15 Phase 3): the literal fixture tickets\n// + synthetic CRM records from spec Section 3a/3c, used to test the\n// orchestration, tool-use branching, and escalation gate against known-good\n// data before any real Claude API call exists (Phase 7). This node is its\n// own entry point -- run it directly via n8n's \"Execute step\" -- rather\n// than sitting behind a dedicated trigger node. A real n8n instance\n// silently drops a workflow's second n8n-nodes-base.manualTrigger node\n// (confirmed by live import: 31 of 32 nodes survived, the missing one was\n// a second Manual Trigger); the custom simulator never caught this since\n// it just executes the committed JSON directly and doesn't enforce n8n's\n// own editor-level constraints. Since this node needs no real input\n// (it returns literal fixture data regardless), dropping the redundant\n// trigger and executing it directly is a genuine simplification, not a\n// workaround.\nconst FIXTURE_TICKETS = [\n  {\n    \"complaint_id\": \"9999970\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"Other debt\",\n    \"issue\": \"Written notification about debt\",\n    \"sub_issue\": \"Didn't receive notice of right to dispute\",\n    \"company\": \"Aargon Agency, Inc.\",\n    \"state\": \"MI\",\n    \"tags\": \"Servicemember\",\n    \"date_received\": \"2024-09-03T22:24:41.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"Requested debt validation after the 30-day window; says the collector never sent it; disputes dates in the collector's own CFPB reply; mentions an attorney and the FTC\",\n    \"crm\": {\n      \"account_id\": \"SYN-FIXTURE-A\",\n      \"linked_complaint_id\": \"9999970\",\n      \"customer_since\": \"2018-09-03\",\n      \"tenure_years\": 6,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Personal Loan\"\n      ],\n      \"outstanding_balance_usd\": 2340,\n      \"prior_complaints_12mo\": 1,\n      \"prior_contacts_90d\": 1,\n      \"preferred_channel\": \"Phone\",\n      \"servicemember_flag\": true,\n      \"special_population_flag\": true\n    }\n  },\n  {\n    \"complaint_id\": \"9999975\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"I do not know\",\n    \"issue\": \"Attempts to collect debt not owed\",\n    \"sub_issue\": \"Debt is not yours\",\n    \"company\": \"EQUIFAX, INC.\",\n    \"state\": \"SC\",\n    \"tags\": null,\n    \"date_received\": \"2024-09-03T22:28:25.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"Reviewed credit report and found accounts believed fraudulent, opened without consent\",\n    \"crm\": {\n      \"account_id\": \"SYN-FIXTURE-B\",\n      \"linked_complaint_id\": \"9999975\",\n      \"customer_since\": \"2023-09-03\",\n      \"tenure_years\": 1,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Checking Account\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 0,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"9999983\",\n    \"product\": \"Credit card\",\n    \"sub_product\": \"General-purpose credit card or charge card\",\n    \"issue\": \"Getting a credit card\",\n    \"sub_issue\": \"Card opened without my consent or knowledge\",\n    \"company\": \"JPMORGAN CHASE & CO.\",\n    \"state\": \"MA\",\n    \"tags\": null,\n    \"date_received\": \"2024-09-03T22:07:34.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"Describes a call about a bank-flagged fraud case, being transferred, then disconnected with no follow-up received\",\n    \"crm\": {\n      \"account_id\": \"SYN-FIXTURE-C\",\n      \"linked_complaint_id\": \"9999983\",\n      \"customer_since\": \"2021-09-03\",\n      \"tenure_years\": 3,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Checking Account\",\n        \"Credit Card\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 0,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24158082\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"Other debt\",\n    \"issue\": \"Written notification about debt\",\n    \"sub_issue\": \"Didn't receive notice of right to dispute\",\n    \"company\": \"American Profit Recovery, Inc., Marlborough, MA Branch\",\n    \"state\": \"TX\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:13:58.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"Debt Collection Complaint I am disputing this alleged debt because I do not believe I owe the amount being claimed. I enrolled in a payment plan for my XXXX XXXX (formerly referred to as XXXX or XXXX XXXX XXXX) equipment and made my required monthly payments. My understanding was that the agreement would end after approximately 12 months. When my payment term was complete, a technician came to retrieve the handheld equipment. Before surrendering the equipment, I specifically asked whether my account was paid in full. Although the technician mentioned he was new and could not verify every detail in the system, he proceeded to collect the equipment and provided me with a printed receipt showing a balance of $0.00. To my understanding, the company would not have been able to retrieve the equipment or close out that portion of my account if there had been an outstanding balance. Based on the receipt showing a XXXX balance and the fact that the equipment was accepted and removed from my possession, I reasonably believed my account was fully satisfied. Now, after a significant amount of time has passed, I have learned that a collection account for approximately $550.00 has been reported or is being collected. I was never made aware of this alleged balance because any notices were apparently sent to an address where I have not lived for over three years. As a result, I had no opportunity to address or dispute the alleged debt before it was sent to collections. I respectfully request that this account be investigated. If the creditor claims I owe this balance, I request complete validation of the debt, including: a detailed accounting showing how the alleged balance of approximately $550.00 was calculated, copies of any agreement or contract demonstrating that I remained responsible for this balance, records of all payments made on the account, and documentation explaining why I was issued a receipt showing a $0.00 balance when the equipment was collected. Because I possess documentation showing a XXXX balance at the time the equipment was returned, I dispute the accuracy of this debt and request that the collection activity and any credit reporting be corrected if the debt cannot be properly validated.\",\n    \"crm\": {\n      \"account_id\": \"SYN-1S8MVB7\",\n      \"linked_complaint_id\": \"24158082\",\n      \"customer_since\": \"2016-09-11\",\n      \"tenure_years\": 10,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Certificate of Deposit\",\n        \"Auto Loan\",\n        \"Home Equity Line of Credit\",\n        \"Credit Card\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 3,\n      \"prior_contacts_90d\": 1,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24157871\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"I do not know\",\n    \"issue\": \"Communication tactics\",\n    \"sub_issue\": \"Frequent or repeated calls\",\n    \"company\": \"Collections Acquisition Company, Inc.\",\n    \"state\": \"PA\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:17:07.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"Called me 9 times and left 8 voicemails within 7 minutes. On the 9th straight call I picked up and told them I work nights and am trying to sleep and to not call me again and they hung up. After researching the number they called from I discovered it is for a debt that I have already paid.\",\n    \"crm\": {\n      \"account_id\": \"SYN-17YTGVQ\",\n      \"linked_complaint_id\": \"24157871\",\n      \"customer_since\": \"2023-10-06\",\n      \"tenure_years\": 3,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Certificate of Deposit\",\n        \"Personal Loan\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 1,\n      \"prior_contacts_90d\": 0,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24157473\",\n    \"product\": \"Credit card\",\n    \"sub_product\": \"General-purpose credit card or charge card\",\n    \"issue\": \"Fees or interest\",\n    \"sub_issue\": \"Problem with fees\",\n    \"company\": \"U.S. BANCORP\",\n    \"state\": \"MA\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:02:31.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"On XX/XX/year>, I closed my US Bank XXXX XXXX XXXX XXXX, which has a $400.00 annual fee. As a Massachusetts resident, I requested a pro-rated annual fee refund afforded to me by Massachusetts General Laws Chapter 140, Section 114C. I received a letter (image attached) dated XX/XX/XXXX, stating that they would not be refunding this fee. U.S. Bank is violating Massachusetts General Laws Chapter 140, Section 114C by denying a legally mandated two-thirds prorated annual fee refund upon account closure.\",\n    \"crm\": {\n      \"account_id\": \"SYN-HQZST8\",\n      \"linked_complaint_id\": \"24157473\",\n      \"customer_since\": \"2023-06-20\",\n      \"tenure_years\": 3,\n      \"account_tier\": \"Preferred\",\n      \"product_holdings\": [\n        \"Personal Loan\",\n        \"Home Equity Line of Credit\"\n      ],\n      \"outstanding_balance_usd\": 4545.59,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 1,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24157200\",\n    \"product\": \"Credit card\",\n    \"sub_product\": \"General-purpose credit card or charge card\",\n    \"issue\": \"Trouble using your card\",\n    \"sub_issue\": \"Credit card company won't increase or decrease your credit limit\",\n    \"company\": \"WELLS FARGO & COMPANY\",\n    \"state\": \"NJ\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:03:45.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"On XX/XX/year>, Wells Fargo denied my request for a credit limit increase on my credit card account ending XXXX, citing a single reason: unacceptable past credit history. The denial letter contains none of the disclosures required by FCRA (XXXX)(XXXX XXXX. XXXX (XXXX)) when adverse action is based in whole or in part on a consumer report: it does not identify any consumer reporting agency, does not provide the agency's contact information, does not disclose the credit score used or its range and key factors, and does not state my right to obtain a free copy of the report or to dispute its contents.\",\n    \"crm\": {\n      \"account_id\": \"SYN-FBM1I0\",\n      \"linked_complaint_id\": \"24157200\",\n      \"customer_since\": \"2021-04-06\",\n      \"tenure_years\": 5,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Auto Loan\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 2,\n      \"prior_contacts_90d\": 2,\n      \"preferred_channel\": \"Phone\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24157609\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"I do not know\",\n    \"issue\": \"Attempts to collect debt not owed\",\n    \"sub_issue\": \"Debt was result of identity theft\",\n    \"company\": \"CL Holdings LLC\",\n    \"state\": \"TX\",\n    \"tags\": \"Servicemember\",\n    \"date_received\": \"2026-07-14T00:11:22.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with non-monetary relief\",\n    \"complaint_what_happened\": \"\",\n    \"crm\": {\n      \"account_id\": \"SYN-TTYX3Z\",\n      \"linked_complaint_id\": \"24157609\",\n      \"customer_since\": \"2016-03-10\",\n      \"tenure_years\": 10,\n      \"account_tier\": \"Standard\",\n      \"product_holdings\": [\n        \"Credit Card\",\n        \"Home Equity Line of Credit\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 0,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": true,\n      \"special_population_flag\": true\n    }\n  },\n  {\n    \"complaint_id\": \"24157195\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"I do not know\",\n    \"issue\": \"Attempts to collect debt not owed\",\n    \"sub_issue\": \"Debt is not yours\",\n    \"company\": \"ProCollect, Inc.\",\n    \"state\": \"NM\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:04:51.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"\",\n    \"crm\": {\n      \"account_id\": \"SYN-TWYBB\",\n      \"linked_complaint_id\": \"24157195\",\n      \"customer_since\": \"2023-06-05\",\n      \"tenure_years\": 3,\n      \"account_tier\": \"Preferred\",\n      \"product_holdings\": [\n        \"Credit Card\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 1,\n      \"preferred_channel\": \"Web\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  },\n  {\n    \"complaint_id\": \"24157240\",\n    \"product\": \"Debt collection\",\n    \"sub_product\": \"I do not know\",\n    \"issue\": \"Attempts to collect debt not owed\",\n    \"sub_issue\": \"Debt is not yours\",\n    \"company\": \"Security Credit Services, LLC\",\n    \"state\": \"NM\",\n    \"tags\": null,\n    \"date_received\": \"2026-07-14T00:06:48.000Z\",\n    \"timely\": \"Yes\",\n    \"company_response\": \"Closed with explanation\",\n    \"complaint_what_happened\": \"\",\n    \"crm\": {\n      \"account_id\": \"SYN-D441JW\",\n      \"linked_complaint_id\": \"24157240\",\n      \"customer_since\": \"2025-10-14\",\n      \"tenure_years\": 1,\n      \"account_tier\": \"Preferred\",\n      \"product_holdings\": [\n        \"Checking Account\"\n      ],\n      \"outstanding_balance_usd\": 0,\n      \"prior_complaints_12mo\": 0,\n      \"prior_contacts_90d\": 0,\n      \"preferred_channel\": \"Phone\",\n      \"servicemember_flag\": false,\n      \"special_population_flag\": false\n    }\n  }\n];\nreturn FIXTURE_TICKETS.map((t) => ({ json: t }));"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000002",
      "name": "Load Fixture Tickets",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -400,
        320
      ],
      "notesInFlow": true,
      "notes": "Phase 3 test harness: injects the literal Section 3a/3c Ticket A/B/C fixtures, bypassing the live CFPB fetch and random CRM generation entirely. Its own entry point -- no dedicated trigger node (see the code comment on jsLoadFixtureTickets); run it directly via n8n's \"Execute step\"."
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001b",
      "name": "Merge: Fixture or Live Tickets",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        580,
        60
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Both the live pipeline (Phase 1 fetch -> Phase 2 CRM) and the Fixture Test\n// Trigger converge here. Phase 3's mock agents only have known-good fixture\n// data for Tickets A/B/C -- route anything else to a clearly-labelled\n// \"awaiting Phase 7\" dead end instead of letting it fall through into agents\n// that would have to fabricate a result for it.\nconst FIXTURE_IDS = [\"9999970\",\"9999975\",\"9999983\",\"24158082\",\"24157871\",\"24157473\",\"24157200\",\"24157609\",\"24157195\",\"24157240\"];\nconst ticket = $input.item.json;\nreturn { json: { ...ticket, is_fixture_ticket: FIXTURE_IDS.includes(String(ticket.complaint_id)) } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000003",
      "name": "Route: Fixture or Live?",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        740,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-000000000004-cond",
              "leftValue": "={{ $json.is_fixture_ticket }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000004",
      "name": "IF: Is Fixture Ticket?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        960,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: \"claude-haiku-4-5-20251001\", max_tokens: 1536, system: \"You are Agent 1 (Classification) in a complaint-triage pipeline processing a real CFPB consumer complaint.\\n\\nTask: identify the substantive issue(s) the consumer is actually raising. When the narrative describes more than one issue, rank them by severity and substance -- NOT by how much narrative text each one occupies. (A known failure mode this pipeline was specifically built to avoid: an earlier draft classified a complaint by whichever issue had the most narrative text, a dropped phone call, instead of the issue the consumer had actually filed as substantive, an unauthorised account. Do not repeat that mistake.)\\n\\nDecide whether the taxonomy-lookup tool is needed: set tool_used=true ONLY when the narrative is genuinely ambiguous relative to the ticket's own filed category (its product/issue/sub_issue fields) -- not for clear, clean-match cases.\\n\\nRespond with ONLY this JSON shape, no other text:\\n{\\n  \\\"tool_used\\\": boolean,\\n  \\\"issues\\\": [{ \\\"issue\\\": string, \\\"severity\\\": \\\"Low\\\" | \\\"Medium\\\" | \\\"High\\\", \\\"confidence\\\": number (0-1), \\\"basis\\\": string }],\\n  \\\"primary_issue\\\": string\\n}\\n\\\"issues\\\" must have at least one entry. \\\"primary_issue\\\" must exactly match one entry's \\\"issue\\\" value -- the one you judge most substantive.\", messages: [{ role: \"user\", content: JSON.stringify($json) + \"\\n\\nRespond with ONLY valid JSON matching the schema in the system prompt -- no prose, no markdown code fences.\" }] }) }}",
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000001",
      "name": "Real Agent 1: Classification",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1180,
        400
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "notes": "Real Claude API call (spec Section 15 Phase 7). Classifies the complaint's substantive issue(s) and decides whether the taxonomy tool is needed -- same contract as the mock Agent 1 node above."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "function parseAnthropicJson(apiResponse) {\r\n  const text = apiResponse.content?.[0]?.text || \"\";\r\n  const stripped = text.trim().replace(/^```(?:json)?\\n?/i, \"\").replace(/\\n?```$/, \"\");\r\n  return JSON.parse(stripped);\r\n}\n\n// n8n's HTTP Request node replaces the item's json with the raw API\n// response -- it does not merge the response with the original input. So\n// the original ticket (complaint_id, product, crm, etc.) must be pulled\n// back from the node that fed Real Agent 1, by name, rather than assumed\n// to still be present on $input.item.json (which is the API response).\nconst apiResponse = $input.item.json;\nconst originalTicket = $('IF: Is Fixture Ticket?').item.json;\nconst parsed = parseAnthropicJson(apiResponse);\nreturn { json: { ...originalTicket, agent1_tool_used: parsed.tool_used, agent1_output: { issues: parsed.issues, primary_issue: parsed.primary_issue } } };"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000002",
      "name": "Parse: Real Agent 1 Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        400
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c3a8e4b2-0001-4000-8000-000000000003-cond",
              "leftValue": "={{ $json.agent1_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000003",
      "name": "IF: Real Agent 1 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1420,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 1 (real): CFPB product/issue/sub-issue taxonomy lookup -- the same\n// cached snapshot as reference_data/taxonomy/cfpb_taxonomy.json (Phase 1).\n// Searches both issue- and sub-issue-level names, since Agent 1's\n// classification may hand back either.\nconst TAXONOMY = {\"_meta\":{\"description\":\"CFPB Consumer Complaint Database product/issue/sub-issue taxonomy, scoped to the S2.3 pilot categories (Debt collection, Credit card). Backs Agent 1 (Classification)'s taxonomy lookup tool -- spec Section 6.\",\"source\":\"https://www.consumerfinance.gov/data-research/consumer-complaints/search/api/v1/ (live aggregations query, no auth required)\",\"retrieved_date\":\"2026-08-12\",\"scope_note\":\"Pulled once at build time per spec Section 6 / Section 15 Phase 1 -- cached static lookup, not re-fetched per ticket.\"},\"products\":[{\"product\":\"Debt collection\",\"total_complaints_in_scope\":1167638,\"sub_products\":[{\"name\":\"I do not know\",\"doc_count\":474297},{\"name\":\"Other debt\",\"doc_count\":195980},{\"name\":\"Credit card debt\",\"doc_count\":177098},{\"name\":\"Medical debt\",\"doc_count\":76913},{\"name\":\"Other (i.e. phone, health club, etc.)\",\"doc_count\":44436},{\"name\":\"Auto debt\",\"doc_count\":32099},{\"name\":\"Telecommunications debt\",\"doc_count\":30154},{\"name\":\"Credit card\",\"doc_count\":28626},{\"name\":\"Rental debt\",\"doc_count\":28622},{\"name\":\"Medical\",\"doc_count\":21143},{\"name\":\"Payday loan debt\",\"doc_count\":16325},{\"name\":\"Mortgage debt\",\"doc_count\":8496},{\"name\":\"Payday loan\",\"doc_count\":7493},{\"name\":\"Private student loan debt\",\"doc_count\":6058},{\"name\":\"Federal student loan debt\",\"doc_count\":5992},{\"name\":\"Mortgage\",\"doc_count\":4807},{\"name\":\"Auto\",\"doc_count\":3748},{\"name\":\"Non-federal student loan\",\"doc_count\":2878},{\"name\":\"Federal student loan\",\"doc_count\":2473}],\"issues\":[{\"name\":\"Attempts to collect debt not owed\",\"doc_count\":469041,\"sub_issues\":[{\"name\":\"Debt is not yours\",\"doc_count\":262452},{\"name\":\"Debt was result of identity theft\",\"doc_count\":139468},{\"name\":\"Debt was paid\",\"doc_count\":54398},{\"name\":\"Debt was already discharged in bankruptcy and is no longer owed\",\"doc_count\":12723}]},{\"name\":\"Written notification about debt\",\"doc_count\":226489,\"sub_issues\":[{\"name\":\"Didn't receive enough information to verify debt\",\"doc_count\":114695},{\"name\":\"Notification didn't disclose it was an attempt to collect a debt\",\"doc_count\":62578},{\"name\":\"Didn't receive notice of right to dispute\",\"doc_count\":49216}]},{\"name\":\"Took or threatened to take negative or legal action\",\"doc_count\":143350,\"sub_issues\":[{\"name\":\"Threatened or suggested your credit would be damaged\",\"doc_count\":111195},{\"name\":\"Threatened to sue you for very old debt\",\"doc_count\":11131},{\"name\":\"Sued you without properly notifying you of lawsuit\",\"doc_count\":7534},{\"name\":\"Seized or attempted to seize your property\",\"doc_count\":5239},{\"name\":\"Threatened to arrest you or take you to jail if you do not pay\",\"doc_count\":3496},{\"name\":\"Collected or attempted to collect exempt funds\",\"doc_count\":3037},{\"name\":\"Sued you in a state where you do not live or did not sign for the debt\",\"doc_count\":1462},{\"name\":\"Threatened to turn you in to immigration or deport you\",\"doc_count\":256}]},{\"name\":\"False statements or representation\",\"doc_count\":118634,\"sub_issues\":[{\"name\":\"Attempted to collect wrong amount\",\"doc_count\":104998},{\"name\":\"Impersonated attorney, law enforcement, or government official\",\"doc_count\":6304},{\"name\":\"Indicated you were committing crime by not paying debt\",\"doc_count\":3456},{\"name\":\"Impersonated an attorney or official\",\"doc_count\":1284},{\"name\":\"Told you not to respond to a lawsuit they filed against you\",\"doc_count\":1235},{\"name\":\"Indicated committed crime not paying\",\"doc_count\":1012},{\"name\":\"Indicated shouldn't respond to lawsuit\",\"doc_count\":345}]},{\"name\":\"Communication tactics\",\"doc_count\":77065,\"sub_issues\":[{\"name\":\"Frequent or repeated calls\",\"doc_count\":42329},{\"name\":\"You told them to stop contacting you, but they keep trying\",\"doc_count\":16978},{\"name\":\"Used obscene, profane, or other abusive language\",\"doc_count\":6111},{\"name\":\"Threatened to take legal action\",\"doc_count\":4669},{\"name\":\"Called before 8am or after 9pm\",\"doc_count\":2374},{\"name\":\"Called after sent written cease of comm\",\"doc_count\":1852},{\"name\":\"Used obscene/profane/abusive language\",\"doc_count\":1832},{\"name\":\"Called outside of 8am-9pm\",\"doc_count\":912},{\"name\":\"Frequent or repeated messages\",\"doc_count\":4},{\"name\":\"Contacted before 8am or after 9pm\",\"doc_count\":3}]},{\"name\":\"Cont'd attempts collect debt not owed\",\"doc_count\":60520,\"sub_issues\":[{\"name\":\"Debt is not mine\",\"doc_count\":36629},{\"name\":\"Debt was paid\",\"doc_count\":16582},{\"name\":\"Debt resulted from identity theft\",\"doc_count\":4899},{\"name\":\"Debt was discharged in bankruptcy\",\"doc_count\":2410}]},{\"name\":\"Disclosure verification of debt\",\"doc_count\":30728,\"sub_issues\":[{\"name\":\"Not given enough info to verify debt\",\"doc_count\":21757},{\"name\":\"Right to dispute notice not received\",\"doc_count\":7174},{\"name\":\"Not disclosed as an attempt to collect\",\"doc_count\":1797}]},{\"name\":\"Threatened to contact someone or share information improperly\",\"doc_count\":13300,\"sub_issues\":[{\"name\":\"Talked to a third-party about your debt\",\"doc_count\":7634},{\"name\":\"Contacted you after you asked them to stop\",\"doc_count\":2985},{\"name\":\"Contacted your employer\",\"doc_count\":2482},{\"name\":\"Contacted you instead of your attorney\",\"doc_count\":199}]},{\"name\":\"Improper contact or sharing of info\",\"doc_count\":10036,\"sub_issues\":[{\"name\":\"Talked to a third party about my debt\",\"doc_count\":5037},{\"name\":\"Contacted me after I asked not to\",\"doc_count\":2567},{\"name\":\"Contacted employer after asked not to\",\"doc_count\":2192},{\"name\":\"Contacted me instead of my attorney\",\"doc_count\":240}]},{\"name\":\"Electronic communications\",\"doc_count\":9682,\"sub_issues\":[{\"name\":\"Frequent or repeated messages\",\"doc_count\":5850},{\"name\":\"You told them to stop contacting you, but they keep trying\",\"doc_count\":2884},{\"name\":\"Contacted before 8am or after 9pm\",\"doc_count\":680},{\"name\":\"Used obscene, profane, or other abusive language\",\"doc_count\":268}]},{\"name\":\"Taking/threatening an illegal action\",\"doc_count\":8793,\"sub_issues\":[{\"name\":\"Threatened to sue on too old debt\",\"doc_count\":2690},{\"name\":\"Threatened arrest/jail if do not pay\",\"doc_count\":2253},{\"name\":\"Sued w/o proper notification of suit\",\"doc_count\":1387},{\"name\":\"Seized/Attempted to seize property\",\"doc_count\":1159},{\"name\":\"Attempted to/Collected exempt funds\",\"doc_count\":903},{\"name\":\"Sued where didn't live/sign for debt\",\"doc_count\":401}]}]},{\"product\":\"Credit card\",\"total_complaints_in_scope\":333515,\"sub_products\":[{\"name\":\"General-purpose credit card or charge card\",\"doc_count\":217513},{\"name\":\"Store credit card\",\"doc_count\":26817}],\"issues\":[{\"name\":\"Problem with a purchase shown on your statement\",\"doc_count\":57864,\"sub_issues\":[{\"name\":\"Credit card company isn't resolving a dispute about a purchase on your statement\",\"doc_count\":43435},{\"name\":\"Card was charged for something you did not purchase with the card\",\"doc_count\":12841},{\"name\":\"Overcharged for something you did purchase with the card\",\"doc_count\":1588}]},{\"name\":\"Incorrect information on your report\",\"doc_count\":31970,\"sub_issues\":[{\"name\":\"Account status incorrect\",\"doc_count\":23892},{\"name\":\"Account information incorrect\",\"doc_count\":3687},{\"name\":\"Information belongs to someone else\",\"doc_count\":3368},{\"name\":\"Old information reappears or never goes away\",\"doc_count\":401},{\"name\":\"Information is missing that should be on the report\",\"doc_count\":234},{\"name\":\"Personal information incorrect\",\"doc_count\":213},{\"name\":\"Public record information inaccurate\",\"doc_count\":175}]},{\"name\":\"Getting a credit card\",\"doc_count\":30200,\"sub_issues\":[{\"name\":\"Card opened without my consent or knowledge\",\"doc_count\":20460},{\"name\":\"Application denied\",\"doc_count\":6209},{\"name\":\"Sent card you never applied for\",\"doc_count\":1428},{\"name\":\"Delay in processing application\",\"doc_count\":1131},{\"name\":\"Problem getting a working replacement card\",\"doc_count\":972}]},{\"name\":\"Problem with a company's investigation into an existing problem\",\"doc_count\":26306,\"sub_issues\":[{\"name\":\"Was not notified of investigation status or results\",\"doc_count\":20284},{\"name\":\"Their investigation did not fix an error on your report\",\"doc_count\":4654},{\"name\":\"Problem with personal statement of dispute\",\"doc_count\":626},{\"name\":\"Difficulty submitting a dispute or getting information about a dispute over the phone\",\"doc_count\":507},{\"name\":\"Investigation took more than 30 days\",\"doc_count\":235}]},{\"name\":\"Other features, terms, or problems\",\"doc_count\":24417,\"sub_issues\":[{\"name\":\"Other problem\",\"doc_count\":12042},{\"name\":\"Problem with rewards from credit card\",\"doc_count\":5515},{\"name\":\"Problem with customer service\",\"doc_count\":2514},{\"name\":\"Problem with balance transfer\",\"doc_count\":1574},{\"name\":\"Privacy issues\",\"doc_count\":1558},{\"name\":\"Add-on products and services\",\"doc_count\":580},{\"name\":\"Credit card company forcing arbitration\",\"doc_count\":309},{\"name\":\"Problem with cash advances\",\"doc_count\":239},{\"name\":\"Problem with convenience check\",\"doc_count\":86}]},{\"name\":\"Fees or interest\",\"doc_count\":21692,\"sub_issues\":[{\"name\":\"Problem with fees\",\"doc_count\":13275},{\"name\":\"Charged too much interest\",\"doc_count\":6273},{\"name\":\"Unexpected increase in interest rate\",\"doc_count\":2144}]},{\"name\":\"Closing your account\",\"doc_count\":15397,\"sub_issues\":[{\"name\":\"Company closed your account\",\"doc_count\":11972},{\"name\":\"Can't close your account\",\"doc_count\":3425}]},{\"name\":\"Billing disputes\",\"doc_count\":15136,\"sub_issues\":[]},{\"name\":\"Problem when making payments\",\"doc_count\":12937,\"sub_issues\":[{\"name\":\"Problem during payment process\",\"doc_count\":11227},{\"name\":\"You never received your bill or did not know a payment was due\",\"doc_count\":1710}]},{\"name\":\"Other\",\"doc_count\":9350,\"sub_issues\":[]},{\"name\":\"Advertising and marketing, including promotional offers\",\"doc_count\":9134,\"sub_issues\":[{\"name\":\"Didn't receive advertised or promotional terms\",\"doc_count\":5112},{\"name\":\"Confusing or misleading advertising about the credit card\",\"doc_count\":4022}]},{\"name\":\"Identity theft / Fraud / Embezzlement\",\"doc_count\":8480,\"sub_issues\":[]},{\"name\":\"Trouble using your card\",\"doc_count\":8174,\"sub_issues\":[{\"name\":\"Can't use card to make purchases\",\"doc_count\":5530},{\"name\":\"Credit card company won't increase or decrease your credit limit\",\"doc_count\":2485},{\"name\":\"Account sold or transferred to another company\",\"doc_count\":159}]},{\"name\":\"Closing/Cancelling account\",\"doc_count\":6389,\"sub_issues\":[]},{\"name\":\"APR or interest rate\",\"doc_count\":5506,\"sub_issues\":[]},{\"name\":\"Late fee\",\"doc_count\":3639,\"sub_issues\":[]},{\"name\":\"Customer service / Customer relations\",\"doc_count\":3504,\"sub_issues\":[]},{\"name\":\"Delinquent account\",\"doc_count\":3218,\"sub_issues\":[]},{\"name\":\"Struggling to pay your bill\",\"doc_count\":3079,\"sub_issues\":[{\"name\":\"Credit card company won't work with you while you're going through financial hardship\",\"doc_count\":2681},{\"name\":\"Problem lowering your monthly payments\",\"doc_count\":248},{\"name\":\"Filed for bankruptcy\",\"doc_count\":150}]},{\"name\":\"Credit determination\",\"doc_count\":3057,\"sub_issues\":[]},{\"name\":\"Advertising and marketing\",\"doc_count\":2926,\"sub_issues\":[]},{\"name\":\"Rewards\",\"doc_count\":2916,\"sub_issues\":[]},{\"name\":\"Credit card protection / Debt protection\",\"doc_count\":2728,\"sub_issues\":[]},{\"name\":\"Transaction issue\",\"doc_count\":2700,\"sub_issues\":[]},{\"name\":\"Billing statement\",\"doc_count\":2619,\"sub_issues\":[]},{\"name\":\"Payoff process\",\"doc_count\":2315,\"sub_issues\":[]},{\"name\":\"Improper use of your report\",\"doc_count\":2263,\"sub_issues\":[{\"name\":\"Reporting company used your report improperly\",\"doc_count\":1379},{\"name\":\"Credit inquiries on your report that you don't recognize\",\"doc_count\":837},{\"name\":\"Received unsolicited financial product or insurance offers after opting out\",\"doc_count\":24},{\"name\":\"Report provided to employer without your written authorization\",\"doc_count\":23}]},{\"name\":\"Other fee\",\"doc_count\":2198,\"sub_issues\":[]},{\"name\":\"Credit line increase/decrease\",\"doc_count\":2185,\"sub_issues\":[]},{\"name\":\"Unsolicited issuance of credit card\",\"doc_count\":1853,\"sub_issues\":[]},{\"name\":\"Credit reporting\",\"doc_count\":1696,\"sub_issues\":[]},{\"name\":\"Balance transfer\",\"doc_count\":1117,\"sub_issues\":[]},{\"name\":\"Collection practices\",\"doc_count\":1001,\"sub_issues\":[]},{\"name\":\"Collection debt dispute\",\"doc_count\":901,\"sub_issues\":[]},{\"name\":\"Forbearance / Workout plans\",\"doc_count\":556,\"sub_issues\":[]},{\"name\":\"Credit monitoring or identity theft protection services\",\"doc_count\":547,\"sub_issues\":[{\"name\":\"Billing dispute for services\",\"doc_count\":245},{\"name\":\"Problem canceling credit monitoring or identify theft protection service\",\"doc_count\":165},{\"name\":\"Didn't receive services that were advertised\",\"doc_count\":63},{\"name\":\"Problem with product or service terms changing\",\"doc_count\":52},{\"name\":\"Received unwanted marketing or advertising\",\"doc_count\":22}]},{\"name\":\"Application processing delay\",\"doc_count\":540,\"sub_issues\":[]},{\"name\":\"Privacy\",\"doc_count\":489,\"sub_issues\":[]},{\"name\":\"Bankruptcy\",\"doc_count\":448,\"sub_issues\":[]},{\"name\":\"Arbitration\",\"doc_count\":348,\"sub_issues\":[]},{\"name\":\"Sale of account\",\"doc_count\":344,\"sub_issues\":[]},{\"name\":\"Cash advance\",\"doc_count\":245,\"sub_issues\":[]},{\"name\":\"Problem with fraud alerts or security freezes\",\"doc_count\":234,\"sub_issues\":[]},{\"name\":\"Balance transfer fee\",\"doc_count\":221,\"sub_issues\":[]},{\"name\":\"Overlimit fee\",\"doc_count\":215,\"sub_issues\":[]},{\"name\":\"Cash advance fee\",\"doc_count\":196,\"sub_issues\":[]},{\"name\":\"Convenience checks\",\"doc_count\":149,\"sub_issues\":[]},{\"name\":\"Unable to get your credit report or credit score\",\"doc_count\":116,\"sub_issues\":[{\"name\":\"Other problem getting your report or credit score\",\"doc_count\":113},{\"name\":\"Problem getting your free annual credit report\",\"doc_count\":3}]}]}]};\n\nfunction taxonomyLookup(taxonomy, product, categoryName) {\r\n  const productEntry = taxonomy.products.find((p) => p.product === product);\r\n  if (!productEntry) return { found: false, note: `Product '${product}' not in cached taxonomy scope.` };\r\n\r\n  const issueEntry = productEntry.issues.find((i) => i.name === categoryName);\r\n  if (issueEntry) {\r\n    return { found: true, level: \"issue\", issue: issueEntry.name, doc_count: issueEntry.doc_count, sibling_sub_issues: issueEntry.sub_issues.map((s) => s.name) };\r\n  }\r\n\r\n  for (const issue of productEntry.issues) {\r\n    const subIssueEntry = issue.sub_issues.find((s) => s.name === categoryName);\r\n    if (subIssueEntry) {\r\n      return {\r\n        found: true, level: \"sub_issue\", parent_issue: issue.name, sub_issue: subIssueEntry.name,\r\n        doc_count: subIssueEntry.doc_count,\r\n        sibling_sub_issues: issue.sub_issues.map((s) => s.name).filter((n) => n !== categoryName),\r\n      };\r\n    }\r\n  }\r\n\r\n  return { found: false, note: `'${categoryName}' not found as an issue or sub-issue under product '${product}'.` };\r\n}\n\nconst ticket = $input.item.json;\nconst category = (ticket.agent1_output && (ticket.agent1_output.primary_issue || ticket.agent1_output.issue)) || ticket.issue;\nconst result = taxonomyLookup(TAXONOMY, ticket.product, category);\nreturn { json: { ...ticket, agent1_tool_result: result } };"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000004",
      "name": "Tool: Real CFPB Taxonomy Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1620,
        520
      ],
      "notesInFlow": true,
      "notes": "Same real, deterministic taxonomy lookup as the Test path's tool -- reused verbatim, not duplicated logic (see jsTaxonomyTool)."
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000005",
      "name": "Merge: Pre-Real Agent 2",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        1740,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: \"claude-haiku-4-5-20251001\", max_tokens: 1536, system: \"You are Agent 2 (Research) in a complaint-triage pipeline. You receive a CFPB complaint ticket plus Agent 1's classification of it.\\n\\nTask: determine which federal regulation, if any, applies to this complaint and why, based on the narrative and the classified issue. Do not guess a citation you're not reasonably confident about -- it is genuinely fine to return null if nothing clearly applies; a downstream deterministic tool independently re-checks your claim against a real cached regulation corpus.\\n\\nDecide whether a broader CRM context pull (tenure, account tier, product holdings, balance, prior-complaint history) is warranted: set broader_crm_lookup_used=true when the customer relationship history seems relevant to responding appropriately (e.g. a repeat complainant, a high-value account, or the issue's nature calls for account context) -- this is discretionary, not automatic.\\n\\nRespond with ONLY this JSON shape, no other text:\\n{\\n  \\\"broader_crm_lookup_used\\\": boolean,\\n  \\\"applicable_regulation\\\": string or null,\\n  \\\"citation\\\": string or null,\\n  \\\"precedent_notes\\\": string\\n}\", messages: [{ role: \"user\", content: JSON.stringify($json) + \"\\n\\nRespond with ONLY valid JSON matching the schema in the system prompt -- no prose, no markdown code fences.\" }] }) }}",
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000006",
      "name": "Real Agent 2: Research",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1860,
        400
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "notes": "Real Claude API call. Determines the applicable regulation (if any) and whether broader CRM context is warranted."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "function parseAnthropicJson(apiResponse) {\r\n  const text = apiResponse.content?.[0]?.text || \"\";\r\n  const stripped = text.trim().replace(/^```(?:json)?\\n?/i, \"\").replace(/\\n?```$/, \"\");\r\n  return JSON.parse(stripped);\r\n}\n\n// See Parse: Real Agent 1 Response for why originalTicket is pulled from\n// the upstream node by name instead of $input.item.json.\nconst apiResponse = $input.item.json;\nconst originalTicket = $('Merge: Pre-Real Agent 2').item.json;\nconst parsed = parseAnthropicJson(apiResponse);\nreturn {\n  json: {\n    ...originalTicket,\n    agent2_broader_crm_lookup_used: parsed.broader_crm_lookup_used,\n    agent2_output: { applicable_regulation: parsed.applicable_regulation, citation: parsed.citation, precedent_notes: parsed.precedent_notes },\n  },\n};"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000007",
      "name": "Parse: Real Agent 2 Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1980,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2, tier 1 (real, always runs -- spec v5): a deterministic yes/no read\n// off the CRM record, not a judgment call, so it is exempted from Agent 2's\n// usual discretion and checked on every ticket. Carried as its own structured\n// field so Agent 4 reads it as data, not buried in free-text customer_context.\nconst ticket = $input.item.json;\nconst special_population_flag = Boolean(ticket.crm.special_population_flag);\nreturn {\n  json: {\n    ...ticket,\n    agent2_special_population_flag: special_population_flag,\n    agent2_output: { ...ticket.agent2_output, special_population_flag },\n  },\n};"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000008",
      "name": "Tool: Real Special Population Check",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2100,
        400
      ],
      "notesInFlow": true,
      "notes": "Always runs, every ticket -- same deterministic CRM read as the Test path's tool."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2, tier 2 (real, always runs -- spec Section 6: \"(b) always, based on\n// classification\"). Keyword + light synonym search across the cached\n// regulation corpus' topics (reference_data/regulations/*.json _meta) to\n// surface candidate applicable regulations. This is deliberately a simple,\n// deterministic lookup, not semantic search -- see README for the honest\n// limitation this implies.\nconst REGULATION_META_INDEX = {\n  \"fdcpa_1692g\": {\n    \"regulation\": \"FDCPA\",\n    \"citation\": \"15 U.S.C. \u00a71692g\",\n    \"topic\": \"Debt validation notice\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1692g\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"fdcpa_1692e\": {\n    \"regulation\": \"FDCPA\",\n    \"citation\": \"15 U.S.C. \u00a71692e\",\n    \"topic\": \"False or misleading representations\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1692e\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"fcra_1681c-2\": {\n    \"regulation\": \"FCRA\",\n    \"citation\": \"15 U.S.C. \u00a71681c-2\",\n    \"topic\": \"Identity-theft block procedure\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"reg_z_1026_13\": {\n    \"regulation\": \"Regulation Z (FCBA)\",\n    \"citation\": \"12 CFR \u00a71026.13\",\n    \"topic\": \"Billing-error resolution procedure\",\n    \"source_url\": \"https://www.law.cornell.edu/cfr/text/12/1026.13\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"cfpb_15day_rule\": {\n    \"regulation\": \"CFPB complaint rule\",\n    \"citation\": \"Dodd-Frank Act company-response standard\",\n    \"topic\": \"Company response deadline\",\n    \"source_url\": \"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\n    \"sourcing_note\": \"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"\n  }\n};\nconst REGULATION_SEARCH_STOPWORDS = new Set([\"debt\",\"debts\",\"credit\",\"card\",\"cards\",\"collection\",\"collector\",\"consumer\",\"consumers\",\"company\",\"companies\",\"account\",\"accounts\",\"with\",\"that\",\"this\",\"from\",\"were\",\"have\",\"been\",\"into\",\"about\",\"attempts\",\"review\",\"reviewed\",\"found\",\"believe\",\"believed\"]);\nconst REGULATION_SEARCH_SYNONYMS = {\"fraud\":\"identity-theft\",\"fraudulent\":\"identity-theft\",\"identity\":\"identity-theft\",\"theft\":\"identity-theft\",\"unauthorized\":\"identity-theft\",\"stolen\":\"identity-theft\",\"false\":\"misleading\",\"deceptive\":\"misleading\",\"misrepresentation\":\"misleading\",\"wrong\":\"billing-error\",\"incorrect\":\"billing-error\",\"error\":\"billing-error\",\"validate\":\"validation\",\"validating\":\"validation\"};\nconst REGULATION_SEARCH_PHRASE_SYNONYMS = [\n  {\n    \"phrases\": [\n      \"fraudulent\",\n      \"not mine\",\n      \"don't recognize\",\n      \"do not recognize\",\n      \"identity theft\",\n      \"unauthorized\"\n    ],\n    \"addsTerm\": \"identity-theft\"\n  },\n  {\n    \"phrases\": [\n      \"didn't receive\",\n      \"did not receive\",\n      \"never received\",\n      \"never got\",\n      \"never sent\",\n      \"no notice\",\n      \"without notice\"\n    ],\n    \"addsTerm\": \"validation\"\n  }\n];\n\nfunction regulationIndexLookup(regulationMetaIndex, stopwords, synonyms, phraseSynonyms, queryText) {\r\n  const lowerQuery = queryText.toLowerCase();\r\n  const rawTerms = lowerQuery.split(/[^a-z-]+/).filter((t) => t.length > 4 && !stopwords.has(t));\r\n  const tokenTerms = rawTerms.flatMap((t) => [t, synonyms[t]].filter(Boolean));\r\n  const phraseTerms = phraseSynonyms.filter((ps) => ps.phrases.some((p) => lowerQuery.includes(p))).map((ps) => ps.addsTerm);\r\n  const terms = [...new Set([...tokenTerms, ...phraseTerms])];\r\n  const matches = [];\r\n  for (const [id, meta] of Object.entries(regulationMetaIndex)) {\r\n    const haystack = meta.topic.toLowerCase();\r\n    const hit = terms.filter((t) => haystack.includes(t));\r\n    if (hit.length > 0) matches.push({ id, citation: meta.citation, topic: meta.topic, matched_terms: hit });\r\n  }\r\n  return matches;\r\n}\n\nconst ticket = $input.item.json;\nconst category = (ticket.agent1_output && (ticket.agent1_output.primary_issue || ticket.agent1_output.issue)) || ticket.issue;\nconst queryText = `${ticket.issue} ${category} ${ticket.complaint_what_happened || \"\"}`;\nconst result = regulationIndexLookup(REGULATION_META_INDEX, REGULATION_SEARCH_STOPWORDS, REGULATION_SEARCH_SYNONYMS, REGULATION_SEARCH_PHRASE_SYNONYMS, queryText);\nreturn { json: { ...ticket, agent2_regulation_tool_result: result } };"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000009",
      "name": "Tool: Real Regulation Index Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2280,
        400
      ],
      "notesInFlow": true,
      "notes": "Always runs -- independently cross-checks Real Agent 2's own regulation claim against the real cached corpus."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c3a8e4b2-0001-4000-8000-00000000000a-cond",
              "leftValue": "={{ $json.agent2_broader_crm_lookup_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000a",
      "name": "IF: Real Agent 2 Broader CRM Lookup Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2460,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2a (real, discretionary -- spec Section 6): the broader CRM context\n// pull (tenure, tier, holdings, balance, prior complaints), gated on Agent\n// 2's mock decision. Reads directly off the synthetic CRM record (Phase 2) --\n// no separate lookup needed, the record already travels with the ticket.\nconst ticket = $input.item.json;\nconst crm = ticket.crm;\nreturn {\n  json: {\n    ...ticket,\n    agent2_crm_tool_result: {\n      tenure_years: crm.tenure_years,\n      account_tier: crm.account_tier,\n      product_holdings: crm.product_holdings,\n      outstanding_balance_usd: crm.outstanding_balance_usd,\n      prior_complaints_12mo: crm.prior_complaints_12mo,\n    },\n  },\n};"
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000b",
      "name": "Tool: Real CRM Broader Context Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2720,
        520
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000c",
      "name": "Merge: Pre-Real Agent 3",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        2840,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: \"claude-haiku-4-5-20251001\", max_tokens: 1536, system: \"You are Agent 3 (Drafting) in a complaint-triage pipeline. You receive a CFPB complaint ticket, Agent 1's classification, and Agent 2's research (applicable regulation and citation, if any).\\n\\nTask: draft a response to the consumer addressing their complaint substantively.\\n\\nDecide whether your draft cites a specific regulatory provision: set cites_regulation=true and cited_clause to the exact citation string ONLY when Agent 2 identified a specific citation AND it's appropriate to cite it in this response. When you do cite it, set tool_used=true so a downstream tool can fetch and verify the exact clause text you're relying on.\\n\\nRespond with ONLY this JSON shape, no other text:\\n{\\n  \\\"tool_used\\\": boolean,\\n  \\\"draft\\\": string,\\n  \\\"cites_regulation\\\": boolean,\\n  \\\"cited_clause\\\": string or null\\n}\", messages: [{ role: \"user\", content: JSON.stringify($json) + \"\\n\\nRespond with ONLY valid JSON matching the schema in the system prompt -- no prose, no markdown code fences.\" }] }) }}",
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000d",
      "name": "Real Agent 3: Drafting",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2960,
        400
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "notes": "Real Claude API call. Drafts the response and decides whether it cites a specific regulatory provision."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "function parseAnthropicJson(apiResponse) {\r\n  const text = apiResponse.content?.[0]?.text || \"\";\r\n  const stripped = text.trim().replace(/^```(?:json)?\\n?/i, \"\").replace(/\\n?```$/, \"\");\r\n  return JSON.parse(stripped);\r\n}\n\n// See Parse: Real Agent 1 Response for why originalTicket is pulled from\n// the upstream node by name instead of $input.item.json.\nconst apiResponse = $input.item.json;\nconst originalTicket = $('Merge: Pre-Real Agent 3').item.json;\nconst parsed = parseAnthropicJson(apiResponse);\nreturn {\n  json: {\n    ...originalTicket,\n    agent3_tool_used: parsed.tool_used,\n    agent3_output: { draft: parsed.draft, cites_regulation: parsed.cites_regulation },\n    _agent3_cited_clause: parsed.cited_clause,\n  },\n};"
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000e",
      "name": "Parse: Real Agent 3 Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3080,
        400
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c3a8e4b2-0001-4000-8000-00000000000f-cond",
              "leftValue": "={{ $json.agent3_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-00000000000f",
      "name": "IF: Real Agent 3 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3200,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 3 (real): exact regulation clause fetch -- parses a citation like\n// \"15 U.S.C. \u00a71692g(b)\" and extracts just that lettered subsection from the\n// cached verbatim regulation text (reference_data/regulations/*.json). Falls\n// back to the full section text when the citation doesn't name a subsection.\nconst REGULATIONS = {\"fdcpa_1692g\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692g\",\"topic\":\"Debt validation notice\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692g\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692g - Validation of debts\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Notice of debt; contents Within five days after the initial communication with a consumer in connection with the collection of any debt, a debt collector shall, unless the following information is contained in the initial communication or the consumer has paid the debt, send the consumer a written notice containing\u2014\\n(1)\\nthe amount of the debt;\\n(2)\\nthe name of the creditor to whom the debt is owed;\\n(3)\\na statement that unless the consumer, within thirty days after receipt of the notice, disputes the validity of the debt, or any portion thereof, the debt will be assumed to be valid by the debt collector;\\n(4)\\na statement that if the consumer notifies the debt collector in writing within the thirty-day period that the debt, or any portion thereof, is disputed, the debt collector will obtain verification of the debt or a copy of a judgment against the consumer and a copy of such verification or judgment will be mailed to the consumer by the debt collector; and\\n(5)\\na statement that, upon the consumer\u2019s written request within the thirty-day period, the debt collector will provide the consumer with the name and address of the original creditor, if different from the current creditor.\\n(b) Disputed debts\\nIf the consumer notifies the debt collector in writing within the thirty-day period described in subsection (a) that the debt, or any portion thereof, is disputed, or that the consumer requests the name and address of the original creditor, the debt collector shall cease collection of the debt, or any disputed portion thereof, until the debt collector obtains verification of the debt or a copy of a judgment, or the name and address of the original creditor, and a copy of such verification or judgment, or name and address of the original creditor, is mailed to the consumer by the debt collector. Collection activities and communications that do not otherwise violate this subchapter may continue during the 30-day period referred to in subsection (a) unless the consumer has notified the debt collector in writing that the debt, or any portion of the debt, is disputed or that the consumer requests the name and address of the original creditor. Any collection activities and communication during the 30-day period may not overshadow or be inconsistent with the disclosure of the consumer\u2019s right to dispute the debt or request the name and address of the original creditor.\\n(c) Admission of liability\\nThe failure of a consumer to dispute the validity of a debt under this section may not be construed by any court as an admission of liability by the consumer.\\n(d) Legal pleadings\\nA communication in the form of a formal pleading in a civil action shall not be treated as an initial communication for purposes of subsection (a).\\n(e) Notice provisions\\nThe sending or delivery of any form or notice which does not relate to the collection of a debt and is expressly required by title 26, title V of Gramm-Leach-Bliley Act [ 15 U.S.C. 6801 et seq.], or any provision of Federal or State law relating to notice of data security breach or privacy, or any regulation prescribed under any such provision of law, shall not be treated as an initial communication in connection with debt collection for purposes of this section.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f809, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 879; amended Pub. L. 109\u2013351, title VIII, \u00a7\u202f802, Oct. 13, 2006, 120 Stat. 2006.)\"},\"fdcpa_1692e\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692e\",\"topic\":\"False or misleading representations\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692e\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692e - False or misleading representations\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\nA debt collector may not use any false, deceptive, or misleading representation or means in connection with the collection of any debt. Without limiting the general application of the foregoing, the following conduct is a violation of this section:\\n(1)\\nThe false representation or implication that the debt collector is vouched for, bonded by, or affiliated with the United States or any State, including the use of any badge, uniform, or facsimile thereof.\\n(2) The false representation of\u2014\\n(A)\\nthe character, amount, or legal status of any debt; or\\n(B)\\nany services rendered or compensation which may be lawfully received by any debt collector for the collection of a debt.\\n(3)\\nThe false representation or implication that any individual is an attorney or that any communication is from an attorney.\\n(4)\\nThe representation or implication that nonpayment of any debt will result in the arrest or imprisonment of any person or the seizure, garnishment, attachment, or sale of any property or wages of any person unless such action is lawful and the debt collector or creditor intends to take such action.\\n(5)\\nThe threat to take any action that cannot legally be taken or that is not intended to be taken.\\n(6) The false representation or implication that a sale, referral, or other transfer of any interest in a debt shall cause the consumer to\u2014\\n(A)\\nlose any claim or defense to payment of the debt; or\\n(B)\\nbecome subject to any practice prohibited by this subchapter.\\n(7)\\nThe false representation or implication that the consumer committed any crime or other conduct in order to disgrace the consumer.\\n(8)\\nCommunicating or threatening to communicate to any person credit information which is known or which should be known to be false, including the failure to communicate that a disputed debt is disputed.\\n(9)\\nThe use or distribution of any written communication which simulates or is falsely represented to be a document authorized, issued, or approved by any court, official, or agency of the United States or any State, or which creates a false impression as to its source, authorization, or approval.\\n(10)\\nThe use of any false representation or deceptive means to collect or attempt to collect any debt or to obtain information concerning a consumer.\\n(11)\\nThe failure to disclose in the initial written communication with the consumer and, in addition, if the initial communication with the consumer is oral, in that initial oral communication, that the debt collector is attempting to collect a debt and that any information obtained will be used for that purpose, and the failure to disclose in subsequent communications that the communication is from a debt collector, except that this paragraph shall not apply to a formal pleading made in connection with a legal action.\\n(12)\\nThe false representation or implication that accounts have been turned over to innocent purchasers for value.\\n(13)\\nThe false representation or implication that documents are legal process.\\n(14)\\nThe use of any business, company, or organization name other than the true name of the debt collector\u2019s business, company, or organization.\\n(15)\\nThe false representation or implication that documents are not legal process forms or do not require action by the consumer.\\n(16)\\nThe false representation or implication that a debt collector operates or is employed by a consumer reporting agency as defined by section 1681a(f) of this title.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f807, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 877; amended Pub. L. 104\u2013208, div. A, title II, \u00a7\u202f2305(a), Sept. 30, 1996, 110 Stat. 3009\u2013425.)\"},\"fcra_1681c-2\":{\"_meta\":{\"regulation\":\"FCRA\",\"citation\":\"15 U.S.C. \u00a71681c-2\",\"topic\":\"Identity-theft block procedure\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1681c-2 - Block of information resulting from identity theft\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Block Except as otherwise provided in this section, a consumer reporting agency shall block the reporting of any information in the file of a consumer that the consumer identifies as information that resulted from an alleged identity theft, not later than 4 business days after the date of receipt by such agency of\u2014\\n(1)\\nappropriate proof of the identity of the consumer;\\n(2)\\na copy of an identity theft report;\\n(3)\\nthe identification of such information by the consumer; and\\n(4)\\na statement by the consumer that the information is not information relating to any transaction by the consumer.\\n(b) Notification A consumer reporting agency shall promptly notify the furnisher of information identified by the consumer under subsection (a)\u2014\\n(1)\\nthat the information may be a result of identity theft;\\n(2)\\nthat an identity theft report has been filed;\\n(3)\\nthat a block has been requested under this section; and\\n(4)\\nof the effective dates of the block.\\n(c) Authority to decline or rescind\\n(1) In general A consumer reporting agency may decline to block, or may rescind any block, of information relating to a consumer under this section, if the consumer reporting agency reasonably determines that\u2014\\n(A)\\nthe information was blocked in error or a block was requested by the consumer in error;\\n(B)\\nthe information was blocked, or a block was requested by the consumer, on the basis of a material misrepresentation of fact by the consumer relevant to the request to block; or\\n(C)\\nthe consumer obtained possession of goods, services, or money as a result of the blocked transaction or transactions.\\n(2) Notification to consumer\\nIf a block of information is declined or rescinded under this subsection, the affected consumer shall be notified promptly, in the same manner as consumers are notified of the reinsertion of information under section 1681i(a)(5)(B) of this title.\\n(3) Significance of block\\nFor purposes of this subsection, if a consumer reporting agency rescinds a block, the presence of information in the file of a consumer prior to the blocking of such information is not evidence of whether the consumer knew or should have known that the consumer obtained possession of any goods, services, or money as a result of the block.\\n(d) Exception for resellers\\n(1) No reseller file This section shall not apply to a consumer reporting agency, if the consumer reporting agency \u2014\\n(A)\\nis a reseller;\\n(B)\\nis not, at the time of the request of the consumer under subsection (a), otherwise furnishing or reselling a consumer report concerning the information identified by the consumer; and\\n(C)\\ninforms the consumer, by any means, that the consumer may report the identity theft to the Bureau to obtain consumer information regarding identity theft.\\n(2) Reseller with file The sole obligation of the consumer reporting agency under this section, with regard to any request of a consumer under this section, shall be to block the consumer report maintained by the consumer reporting agency from any subsequent use, if\u2014\\n(A)\\nthe consumer, in accordance with the provisions of subsection (a), identifies, to a consumer reporting agency, information in the file of the consumer that resulted from identity theft; and\\n(B)\\nthe consumer reporting agency is a reseller of the identified information.\\n(3) Notice\\nIn carrying out its obligation under paragraph (2), the reseller shall promptly provide a notice to the consumer of the decision to block the file. Such notice shall contain the name, address, and telephone number of each consumer reporting agency from which the consumer information was obtained for resale.\\n(e) Exception for verification companies\\nThe provisions of this section do not apply to a check services company, acting as such, which issues authorizations for the purpose of approving or processing negotiable instruments, electronic fund transfers, or similar methods of payments, except that, beginning 4 business days after receipt of information described in paragraphs (1) through (3) of subsection (a), a check services company shall not report to a national consumer reporting agency described in section 1681a(p) of this title, any information identified in the subject identity theft report as resulting from identity theft.\\n(f) Access to blocked information by law enforcement agencies\\nNo provision of this section shall be construed as requiring a consumer reporting agency to prevent a Federal, State, or local law enforcement agency from accessing blocked information in a consumer file to which the agency could otherwise obtain access under this subchapter.\\n( Pub. L. 90\u2013321, title VI, \u00a7\u202f605B, as added Pub. L. 108\u2013159, title I, \u00a7\u202f152(a), Dec. 4, 2003, 117 Stat. 1964; amended Pub. L. 111\u2013203, title X, \u00a7\u202f1088(a)(2)(C), July 21, 2010, 124 Stat. 2087.)\"},\"reg_z_1026_13\":{\"_meta\":{\"regulation\":\"Regulation Z (FCBA)\",\"citation\":\"12 CFR \u00a71026.13\",\"topic\":\"Billing-error resolution procedure\",\"source_url\":\"https://www.law.cornell.edu/cfr/text/12/1026.13\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"12 CFR \u00a7 1026.13 - Billing error resolution.\\nCFR\\nTable of Popular Names\\nprev | next\\n\u00a7 1026.13 Billing error resolution.\\n(a) Definition of billing error. For purposes of this section, the term billing error means:\\n(1) A reflection on or with a periodic statement of an extension of credit that is not made to the consumer or to a person who has actual, implied, or apparent authority to use the consumer's credit card or open-end credit plan.\\n(2) A reflection on or with a periodic statement of an extension of credit that is not identified in accordance with the requirements of \u00a7\u00a7 1026.7(a)(2) or (b)(2), as applicable, and 1026.8.\\n(3) A reflection on or with a periodic statement of an extension of credit for property or services not accepted by the consumer or the consumer's designee, or not delivered to the consumer or the consumer's designee as agreed.\\n(4) A reflection on a periodic statement of the creditor's failure to credit properly a payment or other credit issued to the consumer's account.\\n(5) A reflection on a periodic statement of a computational or similar error of an accounting nature that is made by the creditor.\\n(6) A reflection on a periodic statement of an extension of credit for which the consumer requests additional clarification, including documentary evidence.\\n(7) The creditor's failure to mail or deliver a periodic statement to the consumer's last known address if that address was received by the creditor, in writing, at least 20 days before the end of the billing cycle for which the statement was required.\\n(b) Billing error notice. A billing error notice is a written notice from a consumer that:\\n(1) Is received by a creditor at the address disclosed under \u00a7 1026.7(a)(9) or (b)(9), as applicable, no later than 60 days after the creditor transmitted the first periodic statement that reflects the alleged billing error;\\n(2) Enables the creditor to identify the consumer's name and account number; and\\n(3) To the extent possible, indicates the consumer's belief and the reasons for the belief that a billing error exists, and the type, date, and amount of the error.\\n(c) Time for resolution; general procedures.\\n(1) The creditor shall mail or deliver written acknowledgment to the consumer within 30 days of receiving a billing error notice, unless the creditor has complied with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within the 30-day period; and\\n(2) The creditor shall comply with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within 2 complete billing cycles (but in no event later than 90 days) after receiving a billing error notice.\\n(d) Rules pending resolution. Until a billing error is resolved under paragraph (e) or (f) of this section, the following rules apply:\\n(1) Consumer's right to withhold disputed amount; collection action prohibited. The consumer need not pay (and the creditor may not try to collect) any portion of any required payment that the consumer believes is related to the disputed amount (including related finance or other charges). If the cardholder has enrolled in an automatic payment plan offered by the card issuer and has agreed to pay the credit card indebtedness by periodic deductions from the cardholder's deposit account, the card issuer shall not deduct any part of the disputed amount or related finance or other charges if a billing error notice is received any time up to 3 business days before the scheduled payment date.\\n(2) Adverse credit reports prohibited. The creditor or its agent shall not (directly or indirectly) make or threaten to make an adverse report to any person about the consumer's credit standing, or report that an amount or account is delinquent, because the consumer failed to pay the disputed amount or related finance or other charges.\\n(3) Acceleration of debt and restriction of account prohibited. A creditor shall not accelerate any part of the consumer's indebtedness or restrict or close a consumer's account solely because the consumer has exercised in good faith rights provided by this section. A creditor may be subject to the forfeiture penalty under 15 U.S.C. 1666(e) for failure to comply with any of the requirements of this section.\\n(4) Permitted creditor actions. A creditor is not prohibited from taking action to collect any undisputed portion of the item or bill; from deducting any disputed amount and related finance or other charges from the consumer's credit limit on the account; or from reflecting a disputed amount and related finance or other charges on a periodic statement, provided that the creditor indicates on or with the periodic statement that payment of any disputed amount and related finance or other charges is not required pending the creditor's compliance with this section.\\n(e) Procedures if billing error occurred as asserted. If a creditor determines that a billing error occurred as asserted, it shall within the time limits in paragraph (c)(2) of this section:\\n(1) Correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable; and\\n(2) Mail or deliver a correction notice to the consumer.\\n(f) Procedures if different billing error or no billing error occurred. If, after conducting a reasonable investigation, a creditor determines that no billing error occurred or that a different billing error occurred from that asserted, the creditor shall within the time limits in paragraph (c)(2) of this section:\\n(1) Mail or deliver to the consumer an explanation that sets forth the reasons for the creditor's belief that the billing error alleged by the consumer is incorrect in whole or in part;\\n(2) Furnish copies of documentary evidence of the consumer's indebtedness, if the consumer so requests; and\\n(3) If a different billing error occurred, correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable.\\n(g) Creditor's rights and duties after resolution. If a creditor, after complying with all of the requirements of this section, determines that a consumer owes all or part of the disputed amount and related finance or other charges, the creditor:\\n(1) Shall promptly notify the consumer in writing of the time when payment is due and the portion of the disputed amount and related finance or other charges that the consumer still owes;\\n(2) Shall allow any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable, during which the consumer can pay the amount due under paragraph (g)(1) of this section without incurring additional finance or other charges;\\n(3) May report an account or amount as delinquent because the amount due under paragraph (g)(1) of this section remains unpaid after the creditor has allowed any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable or 10 days (whichever is longer) during which the consumer can pay the amount; but\\n(4) May not report that an amount or account is delinquent because the amount due under paragraph (g)(1) of the section remains unpaid, if the creditor receives (within the time allowed for payment in paragraph (g)(3) of this section) further written notice from the consumer that any portion of the billing error is still in dispute, unless the creditor also:\\n(i) Promptly reports that the amount or account is in dispute;\\n(ii) Mails or delivers to the consumer (at the same time the report is made) a written notice of the name and address of each person to whom the creditor makes a report; and\\n(iii) Promptly reports any subsequent resolution of the reported delinquency to all persons to whom the creditor has made a report.\\n(h) Reassertion of billing error. A creditor that has fully complied with the requirements of this section has no further responsibilities under this section (other than as provided in paragraph (g)(4) of this section) if a consumer reasserts substantially the same billing error.\\n(i) Relation to Electronic Fund Transfer Act and Regulation E. A creditor shall comply with the requirements of Regulation E, 12 CFR 1005.11, and 1005.18(e) as applicable, governing error resolution rather than those of paragraphs (a), (b), (c), (e), (f), and (h) of this section if:\\n(1) Except with respect to a prepaid account as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs under an agreement between the consumer and a financial institution to extend credit when the consumer's account is overdrawn or to maintain a specified minimum balance in the consumer's account; or\\n(2) With regard to a covered separate credit feature and an asset feature of a prepaid account where both are accessible by a hybrid prepaid-credit card as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs when the hybrid prepaid-credit card accesses both funds in the asset feature of the prepaid account and a credit extension from the credit feature with respect to a particular transaction.\\n[ 76 FR 79772, Dec. 22, 2011, as amended at 81 FR 84369, Nov. 22, 2016]\\nElectronic Fund Transfer Act\\nCFR Toolbox\\nLaw about... Articles from Wex\\nTable of Popular Names\\nParallel Table of Authorities\\nAccessibility\\nAbout LII\\nContact us\\nAdvertise here\\nHelp\\nTerms of use\\nPrivacy\"},\"cfpb_15day_rule\":{\"_meta\":{\"regulation\":\"CFPB complaint rule\",\"citation\":\"Dodd-Frank Act company-response standard\",\"topic\":\"Company response deadline\",\"source_url\":\"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\"sourcing_note\":\"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"},\"text\":\"The Dodd-Frank Wall Street Reform and Consumer Protection Act requires the CFPB to collect, investigate, and respond to consumer complaints about financial products and services. Once the CFPB sends a complaint to a company, the company reviews the information, communicates with the consumer as needed, and determines what action to take in response.\\n\\nCompany responds: your company provides a response within 15 calendar days.\\n\\nIf your response is not final, let us know. Your company will then have up to 60 calendar days to provide a final response.\\n\\nComplaints are typically published on the Consumer Complaint Database after the company responds, or after 15 days, whichever comes first, and the consumer is given the opportunity to review the company's response.\"}};\nconst CITATION_TO_FILE = {\"1692g\":\"fdcpa_1692g\",\"1692e\":\"fdcpa_1692e\",\"1681c-2\":\"fcra_1681c-2\",\"1026.13\":\"reg_z_1026_13\"};\n\nfunction fetchExactClause(regulations, citationToFile, citation) {\r\n  const sectionMatch = citation.match(/(1692[a-z]|1681c-2|1026\\.13)/);\r\n  const subsectionMatch = citation.match(/\\(([a-z])\\)/);\r\n  if (!sectionMatch) return { found: false, note: `Could not parse section from citation '${citation}'.` };\r\n\r\n  const fileKey = citationToFile[sectionMatch[1]];\r\n  const doc = regulations[fileKey];\r\n  if (!doc) return { found: false, note: `No cached regulation file for section '${sectionMatch[1]}'.` };\r\n\r\n  if (!subsectionMatch) {\r\n    return { found: true, citation, full_text: doc.text, note: \"No specific subsection in citation; returning full section text.\" };\r\n  }\r\n\r\n  const letter = subsectionMatch[1];\r\n  const text = doc.text;\r\n  const startMarker = `\\n(${letter})`;\r\n  const startIdx = text.indexOf(startMarker);\r\n  if (startIdx === -1) return { found: false, note: `Subsection (${letter}) not found in ${fileKey}.` };\r\n\r\n  const nextLetterCode = letter.charCodeAt(0) + 1;\r\n  const nextMarker = `\\n(${String.fromCharCode(nextLetterCode)})`;\r\n  let endIdx = text.indexOf(nextMarker, startIdx + 1);\r\n  if (endIdx === -1) endIdx = text.length;\r\n\r\n  return { found: true, citation, subsection: letter, clause_text: text.slice(startIdx, endIdx).trim(), source_citation: doc._meta.citation };\r\n}\n\nconst ticket = $input.item.json;\nconst result = fetchExactClause(REGULATIONS, CITATION_TO_FILE, ticket._agent3_cited_clause);\nreturn { json: { ...ticket, agent3_tool_result: result } };"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000010",
      "name": "Tool: Real Exact Regulation Clause Fetch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3380,
        520
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000011",
      "name": "Merge: Pre-Real Agent 4",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        3500,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: \"claude-haiku-4-5-20251001\", max_tokens: 1536, system: \"You are Agent 4 (QA / escalation-scoring) in a complaint-triage pipeline, the final check before a draft either goes out or gets escalated to a human.\\n\\nTask: review Agent 3's draft against Agent 2's cited regulation and the CRM record. Assess your confidence in the draft's factual accuracy (0-1), whether it requires human review before sending, and a concise reason for that judgment.\\n\\nDecide whether to re-verify a specific claim: set tool_used=true, and fill reverify_clause and/or reverify_crm_field, ONLY when the draft makes a checkable claim worth independently re-confirming (a cited regulation clause, and/or a specific CRM fact like tenure_years or prior_complaints_12mo). reverify_crm_field must be an exact CRM field name if set.\\n\\nRespond with ONLY this JSON shape, no other text:\\n{\\n  \\\"tool_used\\\": boolean,\\n  \\\"confidence\\\": number (0-1),\\n  \\\"requires_human\\\": boolean,\\n  \\\"reason\\\": string,\\n  \\\"reverify_clause\\\": string or null,\\n  \\\"reverify_crm_field\\\": string or null\\n}\", messages: [{ role: \"user\", content: JSON.stringify($json) + \"\\n\\nRespond with ONLY valid JSON matching the schema in the system prompt -- no prose, no markdown code fences.\" }] }) }}",
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000012",
      "name": "Real Agent 4: QA / Escalation-Scoring",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        3620,
        400
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "notes": "Real Claude API call, the final check before a draft ships or escalates. Assesses confidence and whether human review is required."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "function parseAnthropicJson(apiResponse) {\r\n  const text = apiResponse.content?.[0]?.text || \"\";\r\n  const stripped = text.trim().replace(/^```(?:json)?\\n?/i, \"\").replace(/\\n?```$/, \"\");\r\n  return JSON.parse(stripped);\r\n}\n\n// See Parse: Real Agent 1 Response for why originalTicket is pulled from\n// the upstream node by name instead of $input.item.json.\nconst apiResponse = $input.item.json;\nconst originalTicket = $('Merge: Pre-Real Agent 4').item.json;\nconst parsed = parseAnthropicJson(apiResponse);\nreturn {\n  json: {\n    ...originalTicket,\n    agent4_tool_used: parsed.tool_used,\n    agent4_output: { confidence: parsed.confidence, requires_human: parsed.requires_human, reason: parsed.reason },\n    _agent4_reverify_clause: parsed.reverify_clause,\n    _agent4_reverify_crm_field: parsed.reverify_crm_field,\n  },\n};"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000013",
      "name": "Parse: Real Agent 4 Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3740,
        400
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c3a8e4b2-0001-4000-8000-000000000014-cond",
              "leftValue": "={{ $json.agent4_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000014",
      "name": "IF: Real Agent 4 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3860,
        400
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 4 (real): re-verify a cited clause (re-runs the same exact-clause-fetch\n// logic Agent 3 uses, confirming the citation genuinely resolves) and\n// re-check a CRM fact directly off the record, not off Agent 2's paraphrase\n// of it -- catches the case where a draft misquotes what the CRM actually says.\nconst REGULATIONS = {\"fdcpa_1692g\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692g\",\"topic\":\"Debt validation notice\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692g\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692g - Validation of debts\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Notice of debt; contents Within five days after the initial communication with a consumer in connection with the collection of any debt, a debt collector shall, unless the following information is contained in the initial communication or the consumer has paid the debt, send the consumer a written notice containing\u2014\\n(1)\\nthe amount of the debt;\\n(2)\\nthe name of the creditor to whom the debt is owed;\\n(3)\\na statement that unless the consumer, within thirty days after receipt of the notice, disputes the validity of the debt, or any portion thereof, the debt will be assumed to be valid by the debt collector;\\n(4)\\na statement that if the consumer notifies the debt collector in writing within the thirty-day period that the debt, or any portion thereof, is disputed, the debt collector will obtain verification of the debt or a copy of a judgment against the consumer and a copy of such verification or judgment will be mailed to the consumer by the debt collector; and\\n(5)\\na statement that, upon the consumer\u2019s written request within the thirty-day period, the debt collector will provide the consumer with the name and address of the original creditor, if different from the current creditor.\\n(b) Disputed debts\\nIf the consumer notifies the debt collector in writing within the thirty-day period described in subsection (a) that the debt, or any portion thereof, is disputed, or that the consumer requests the name and address of the original creditor, the debt collector shall cease collection of the debt, or any disputed portion thereof, until the debt collector obtains verification of the debt or a copy of a judgment, or the name and address of the original creditor, and a copy of such verification or judgment, or name and address of the original creditor, is mailed to the consumer by the debt collector. Collection activities and communications that do not otherwise violate this subchapter may continue during the 30-day period referred to in subsection (a) unless the consumer has notified the debt collector in writing that the debt, or any portion of the debt, is disputed or that the consumer requests the name and address of the original creditor. Any collection activities and communication during the 30-day period may not overshadow or be inconsistent with the disclosure of the consumer\u2019s right to dispute the debt or request the name and address of the original creditor.\\n(c) Admission of liability\\nThe failure of a consumer to dispute the validity of a debt under this section may not be construed by any court as an admission of liability by the consumer.\\n(d) Legal pleadings\\nA communication in the form of a formal pleading in a civil action shall not be treated as an initial communication for purposes of subsection (a).\\n(e) Notice provisions\\nThe sending or delivery of any form or notice which does not relate to the collection of a debt and is expressly required by title 26, title V of Gramm-Leach-Bliley Act [ 15 U.S.C. 6801 et seq.], or any provision of Federal or State law relating to notice of data security breach or privacy, or any regulation prescribed under any such provision of law, shall not be treated as an initial communication in connection with debt collection for purposes of this section.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f809, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 879; amended Pub. L. 109\u2013351, title VIII, \u00a7\u202f802, Oct. 13, 2006, 120 Stat. 2006.)\"},\"fdcpa_1692e\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692e\",\"topic\":\"False or misleading representations\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692e\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692e - False or misleading representations\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\nA debt collector may not use any false, deceptive, or misleading representation or means in connection with the collection of any debt. Without limiting the general application of the foregoing, the following conduct is a violation of this section:\\n(1)\\nThe false representation or implication that the debt collector is vouched for, bonded by, or affiliated with the United States or any State, including the use of any badge, uniform, or facsimile thereof.\\n(2) The false representation of\u2014\\n(A)\\nthe character, amount, or legal status of any debt; or\\n(B)\\nany services rendered or compensation which may be lawfully received by any debt collector for the collection of a debt.\\n(3)\\nThe false representation or implication that any individual is an attorney or that any communication is from an attorney.\\n(4)\\nThe representation or implication that nonpayment of any debt will result in the arrest or imprisonment of any person or the seizure, garnishment, attachment, or sale of any property or wages of any person unless such action is lawful and the debt collector or creditor intends to take such action.\\n(5)\\nThe threat to take any action that cannot legally be taken or that is not intended to be taken.\\n(6) The false representation or implication that a sale, referral, or other transfer of any interest in a debt shall cause the consumer to\u2014\\n(A)\\nlose any claim or defense to payment of the debt; or\\n(B)\\nbecome subject to any practice prohibited by this subchapter.\\n(7)\\nThe false representation or implication that the consumer committed any crime or other conduct in order to disgrace the consumer.\\n(8)\\nCommunicating or threatening to communicate to any person credit information which is known or which should be known to be false, including the failure to communicate that a disputed debt is disputed.\\n(9)\\nThe use or distribution of any written communication which simulates or is falsely represented to be a document authorized, issued, or approved by any court, official, or agency of the United States or any State, or which creates a false impression as to its source, authorization, or approval.\\n(10)\\nThe use of any false representation or deceptive means to collect or attempt to collect any debt or to obtain information concerning a consumer.\\n(11)\\nThe failure to disclose in the initial written communication with the consumer and, in addition, if the initial communication with the consumer is oral, in that initial oral communication, that the debt collector is attempting to collect a debt and that any information obtained will be used for that purpose, and the failure to disclose in subsequent communications that the communication is from a debt collector, except that this paragraph shall not apply to a formal pleading made in connection with a legal action.\\n(12)\\nThe false representation or implication that accounts have been turned over to innocent purchasers for value.\\n(13)\\nThe false representation or implication that documents are legal process.\\n(14)\\nThe use of any business, company, or organization name other than the true name of the debt collector\u2019s business, company, or organization.\\n(15)\\nThe false representation or implication that documents are not legal process forms or do not require action by the consumer.\\n(16)\\nThe false representation or implication that a debt collector operates or is employed by a consumer reporting agency as defined by section 1681a(f) of this title.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f807, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 877; amended Pub. L. 104\u2013208, div. A, title II, \u00a7\u202f2305(a), Sept. 30, 1996, 110 Stat. 3009\u2013425.)\"},\"fcra_1681c-2\":{\"_meta\":{\"regulation\":\"FCRA\",\"citation\":\"15 U.S.C. \u00a71681c-2\",\"topic\":\"Identity-theft block procedure\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1681c-2 - Block of information resulting from identity theft\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Block Except as otherwise provided in this section, a consumer reporting agency shall block the reporting of any information in the file of a consumer that the consumer identifies as information that resulted from an alleged identity theft, not later than 4 business days after the date of receipt by such agency of\u2014\\n(1)\\nappropriate proof of the identity of the consumer;\\n(2)\\na copy of an identity theft report;\\n(3)\\nthe identification of such information by the consumer; and\\n(4)\\na statement by the consumer that the information is not information relating to any transaction by the consumer.\\n(b) Notification A consumer reporting agency shall promptly notify the furnisher of information identified by the consumer under subsection (a)\u2014\\n(1)\\nthat the information may be a result of identity theft;\\n(2)\\nthat an identity theft report has been filed;\\n(3)\\nthat a block has been requested under this section; and\\n(4)\\nof the effective dates of the block.\\n(c) Authority to decline or rescind\\n(1) In general A consumer reporting agency may decline to block, or may rescind any block, of information relating to a consumer under this section, if the consumer reporting agency reasonably determines that\u2014\\n(A)\\nthe information was blocked in error or a block was requested by the consumer in error;\\n(B)\\nthe information was blocked, or a block was requested by the consumer, on the basis of a material misrepresentation of fact by the consumer relevant to the request to block; or\\n(C)\\nthe consumer obtained possession of goods, services, or money as a result of the blocked transaction or transactions.\\n(2) Notification to consumer\\nIf a block of information is declined or rescinded under this subsection, the affected consumer shall be notified promptly, in the same manner as consumers are notified of the reinsertion of information under section 1681i(a)(5)(B) of this title.\\n(3) Significance of block\\nFor purposes of this subsection, if a consumer reporting agency rescinds a block, the presence of information in the file of a consumer prior to the blocking of such information is not evidence of whether the consumer knew or should have known that the consumer obtained possession of any goods, services, or money as a result of the block.\\n(d) Exception for resellers\\n(1) No reseller file This section shall not apply to a consumer reporting agency, if the consumer reporting agency \u2014\\n(A)\\nis a reseller;\\n(B)\\nis not, at the time of the request of the consumer under subsection (a), otherwise furnishing or reselling a consumer report concerning the information identified by the consumer; and\\n(C)\\ninforms the consumer, by any means, that the consumer may report the identity theft to the Bureau to obtain consumer information regarding identity theft.\\n(2) Reseller with file The sole obligation of the consumer reporting agency under this section, with regard to any request of a consumer under this section, shall be to block the consumer report maintained by the consumer reporting agency from any subsequent use, if\u2014\\n(A)\\nthe consumer, in accordance with the provisions of subsection (a), identifies, to a consumer reporting agency, information in the file of the consumer that resulted from identity theft; and\\n(B)\\nthe consumer reporting agency is a reseller of the identified information.\\n(3) Notice\\nIn carrying out its obligation under paragraph (2), the reseller shall promptly provide a notice to the consumer of the decision to block the file. Such notice shall contain the name, address, and telephone number of each consumer reporting agency from which the consumer information was obtained for resale.\\n(e) Exception for verification companies\\nThe provisions of this section do not apply to a check services company, acting as such, which issues authorizations for the purpose of approving or processing negotiable instruments, electronic fund transfers, or similar methods of payments, except that, beginning 4 business days after receipt of information described in paragraphs (1) through (3) of subsection (a), a check services company shall not report to a national consumer reporting agency described in section 1681a(p) of this title, any information identified in the subject identity theft report as resulting from identity theft.\\n(f) Access to blocked information by law enforcement agencies\\nNo provision of this section shall be construed as requiring a consumer reporting agency to prevent a Federal, State, or local law enforcement agency from accessing blocked information in a consumer file to which the agency could otherwise obtain access under this subchapter.\\n( Pub. L. 90\u2013321, title VI, \u00a7\u202f605B, as added Pub. L. 108\u2013159, title I, \u00a7\u202f152(a), Dec. 4, 2003, 117 Stat. 1964; amended Pub. L. 111\u2013203, title X, \u00a7\u202f1088(a)(2)(C), July 21, 2010, 124 Stat. 2087.)\"},\"reg_z_1026_13\":{\"_meta\":{\"regulation\":\"Regulation Z (FCBA)\",\"citation\":\"12 CFR \u00a71026.13\",\"topic\":\"Billing-error resolution procedure\",\"source_url\":\"https://www.law.cornell.edu/cfr/text/12/1026.13\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"12 CFR \u00a7 1026.13 - Billing error resolution.\\nCFR\\nTable of Popular Names\\nprev | next\\n\u00a7 1026.13 Billing error resolution.\\n(a) Definition of billing error. For purposes of this section, the term billing error means:\\n(1) A reflection on or with a periodic statement of an extension of credit that is not made to the consumer or to a person who has actual, implied, or apparent authority to use the consumer's credit card or open-end credit plan.\\n(2) A reflection on or with a periodic statement of an extension of credit that is not identified in accordance with the requirements of \u00a7\u00a7 1026.7(a)(2) or (b)(2), as applicable, and 1026.8.\\n(3) A reflection on or with a periodic statement of an extension of credit for property or services not accepted by the consumer or the consumer's designee, or not delivered to the consumer or the consumer's designee as agreed.\\n(4) A reflection on a periodic statement of the creditor's failure to credit properly a payment or other credit issued to the consumer's account.\\n(5) A reflection on a periodic statement of a computational or similar error of an accounting nature that is made by the creditor.\\n(6) A reflection on a periodic statement of an extension of credit for which the consumer requests additional clarification, including documentary evidence.\\n(7) The creditor's failure to mail or deliver a periodic statement to the consumer's last known address if that address was received by the creditor, in writing, at least 20 days before the end of the billing cycle for which the statement was required.\\n(b) Billing error notice. A billing error notice is a written notice from a consumer that:\\n(1) Is received by a creditor at the address disclosed under \u00a7 1026.7(a)(9) or (b)(9), as applicable, no later than 60 days after the creditor transmitted the first periodic statement that reflects the alleged billing error;\\n(2) Enables the creditor to identify the consumer's name and account number; and\\n(3) To the extent possible, indicates the consumer's belief and the reasons for the belief that a billing error exists, and the type, date, and amount of the error.\\n(c) Time for resolution; general procedures.\\n(1) The creditor shall mail or deliver written acknowledgment to the consumer within 30 days of receiving a billing error notice, unless the creditor has complied with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within the 30-day period; and\\n(2) The creditor shall comply with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within 2 complete billing cycles (but in no event later than 90 days) after receiving a billing error notice.\\n(d) Rules pending resolution. Until a billing error is resolved under paragraph (e) or (f) of this section, the following rules apply:\\n(1) Consumer's right to withhold disputed amount; collection action prohibited. The consumer need not pay (and the creditor may not try to collect) any portion of any required payment that the consumer believes is related to the disputed amount (including related finance or other charges). If the cardholder has enrolled in an automatic payment plan offered by the card issuer and has agreed to pay the credit card indebtedness by periodic deductions from the cardholder's deposit account, the card issuer shall not deduct any part of the disputed amount or related finance or other charges if a billing error notice is received any time up to 3 business days before the scheduled payment date.\\n(2) Adverse credit reports prohibited. The creditor or its agent shall not (directly or indirectly) make or threaten to make an adverse report to any person about the consumer's credit standing, or report that an amount or account is delinquent, because the consumer failed to pay the disputed amount or related finance or other charges.\\n(3) Acceleration of debt and restriction of account prohibited. A creditor shall not accelerate any part of the consumer's indebtedness or restrict or close a consumer's account solely because the consumer has exercised in good faith rights provided by this section. A creditor may be subject to the forfeiture penalty under 15 U.S.C. 1666(e) for failure to comply with any of the requirements of this section.\\n(4) Permitted creditor actions. A creditor is not prohibited from taking action to collect any undisputed portion of the item or bill; from deducting any disputed amount and related finance or other charges from the consumer's credit limit on the account; or from reflecting a disputed amount and related finance or other charges on a periodic statement, provided that the creditor indicates on or with the periodic statement that payment of any disputed amount and related finance or other charges is not required pending the creditor's compliance with this section.\\n(e) Procedures if billing error occurred as asserted. If a creditor determines that a billing error occurred as asserted, it shall within the time limits in paragraph (c)(2) of this section:\\n(1) Correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable; and\\n(2) Mail or deliver a correction notice to the consumer.\\n(f) Procedures if different billing error or no billing error occurred. If, after conducting a reasonable investigation, a creditor determines that no billing error occurred or that a different billing error occurred from that asserted, the creditor shall within the time limits in paragraph (c)(2) of this section:\\n(1) Mail or deliver to the consumer an explanation that sets forth the reasons for the creditor's belief that the billing error alleged by the consumer is incorrect in whole or in part;\\n(2) Furnish copies of documentary evidence of the consumer's indebtedness, if the consumer so requests; and\\n(3) If a different billing error occurred, correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable.\\n(g) Creditor's rights and duties after resolution. If a creditor, after complying with all of the requirements of this section, determines that a consumer owes all or part of the disputed amount and related finance or other charges, the creditor:\\n(1) Shall promptly notify the consumer in writing of the time when payment is due and the portion of the disputed amount and related finance or other charges that the consumer still owes;\\n(2) Shall allow any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable, during which the consumer can pay the amount due under paragraph (g)(1) of this section without incurring additional finance or other charges;\\n(3) May report an account or amount as delinquent because the amount due under paragraph (g)(1) of this section remains unpaid after the creditor has allowed any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable or 10 days (whichever is longer) during which the consumer can pay the amount; but\\n(4) May not report that an amount or account is delinquent because the amount due under paragraph (g)(1) of the section remains unpaid, if the creditor receives (within the time allowed for payment in paragraph (g)(3) of this section) further written notice from the consumer that any portion of the billing error is still in dispute, unless the creditor also:\\n(i) Promptly reports that the amount or account is in dispute;\\n(ii) Mails or delivers to the consumer (at the same time the report is made) a written notice of the name and address of each person to whom the creditor makes a report; and\\n(iii) Promptly reports any subsequent resolution of the reported delinquency to all persons to whom the creditor has made a report.\\n(h) Reassertion of billing error. A creditor that has fully complied with the requirements of this section has no further responsibilities under this section (other than as provided in paragraph (g)(4) of this section) if a consumer reasserts substantially the same billing error.\\n(i) Relation to Electronic Fund Transfer Act and Regulation E. A creditor shall comply with the requirements of Regulation E, 12 CFR 1005.11, and 1005.18(e) as applicable, governing error resolution rather than those of paragraphs (a), (b), (c), (e), (f), and (h) of this section if:\\n(1) Except with respect to a prepaid account as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs under an agreement between the consumer and a financial institution to extend credit when the consumer's account is overdrawn or to maintain a specified minimum balance in the consumer's account; or\\n(2) With regard to a covered separate credit feature and an asset feature of a prepaid account where both are accessible by a hybrid prepaid-credit card as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs when the hybrid prepaid-credit card accesses both funds in the asset feature of the prepaid account and a credit extension from the credit feature with respect to a particular transaction.\\n[ 76 FR 79772, Dec. 22, 2011, as amended at 81 FR 84369, Nov. 22, 2016]\\nElectronic Fund Transfer Act\\nCFR Toolbox\\nLaw about... Articles from Wex\\nTable of Popular Names\\nParallel Table of Authorities\\nAccessibility\\nAbout LII\\nContact us\\nAdvertise here\\nHelp\\nTerms of use\\nPrivacy\"},\"cfpb_15day_rule\":{\"_meta\":{\"regulation\":\"CFPB complaint rule\",\"citation\":\"Dodd-Frank Act company-response standard\",\"topic\":\"Company response deadline\",\"source_url\":\"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\"sourcing_note\":\"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"},\"text\":\"The Dodd-Frank Wall Street Reform and Consumer Protection Act requires the CFPB to collect, investigate, and respond to consumer complaints about financial products and services. Once the CFPB sends a complaint to a company, the company reviews the information, communicates with the consumer as needed, and determines what action to take in response.\\n\\nCompany responds: your company provides a response within 15 calendar days.\\n\\nIf your response is not final, let us know. Your company will then have up to 60 calendar days to provide a final response.\\n\\nComplaints are typically published on the Consumer Complaint Database after the company responds, or after 15 days, whichever comes first, and the consumer is given the opportunity to review the company's response.\"}};\nconst CITATION_TO_FILE = {\"1692g\":\"fdcpa_1692g\",\"1692e\":\"fdcpa_1692e\",\"1681c-2\":\"fcra_1681c-2\",\"1026.13\":\"reg_z_1026_13\"};\n\nfunction fetchExactClause(regulations, citationToFile, citation) {\r\n  const sectionMatch = citation.match(/(1692[a-z]|1681c-2|1026\\.13)/);\r\n  const subsectionMatch = citation.match(/\\(([a-z])\\)/);\r\n  if (!sectionMatch) return { found: false, note: `Could not parse section from citation '${citation}'.` };\r\n\r\n  const fileKey = citationToFile[sectionMatch[1]];\r\n  const doc = regulations[fileKey];\r\n  if (!doc) return { found: false, note: `No cached regulation file for section '${sectionMatch[1]}'.` };\r\n\r\n  if (!subsectionMatch) {\r\n    return { found: true, citation, full_text: doc.text, note: \"No specific subsection in citation; returning full section text.\" };\r\n  }\r\n\r\n  const letter = subsectionMatch[1];\r\n  const text = doc.text;\r\n  const startMarker = `\\n(${letter})`;\r\n  const startIdx = text.indexOf(startMarker);\r\n  if (startIdx === -1) return { found: false, note: `Subsection (${letter}) not found in ${fileKey}.` };\r\n\r\n  const nextLetterCode = letter.charCodeAt(0) + 1;\r\n  const nextMarker = `\\n(${String.fromCharCode(nextLetterCode)})`;\r\n  let endIdx = text.indexOf(nextMarker, startIdx + 1);\r\n  if (endIdx === -1) endIdx = text.length;\r\n\r\n  return { found: true, citation, subsection: letter, clause_text: text.slice(startIdx, endIdx).trim(), source_citation: doc._meta.citation };\r\n}\n\nconst ticket = $input.item.json;\nconst clause_reverified = fetchExactClause(REGULATIONS, CITATION_TO_FILE, ticket._agent4_reverify_clause);\nconst field = ticket._agent4_reverify_crm_field;\nconst crm_fact_reverified = { field, value: ticket.crm[field] };\nreturn { json: { ...ticket, agent4_tool_result: { clause_reverified, crm_fact_reverified } } };"
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000015",
      "name": "Tool: Real Re-verify Clause & CRM Fact",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4040,
        520
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000016",
      "name": "Merge: Pre-Real Escalation Signals",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        4160,
        400
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "c3a8e4b2-0001-4000-8000-000000000017",
      "name": "Merge: Test/Product Final",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        4200,
        130
      ]
    },
    {
      "parameters": {
        "content": "## \ud83e\uddea Test Path\nFixture-driven, zero API cost \u2014 verifies the pipeline's wiring and logic without spending real Claude credits.",
        "height": 160,
        "width": 340,
        "color": 4
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000001",
      "name": "Sticky: Test Path Label",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        560,
        -260
      ]
    },
    {
      "parameters": {
        "content": "## \ud83d\ude80 Product Path\nReal CFPB tickets, real Claude API calls \u2014 this is what actually runs on the live schedule.",
        "height": 160,
        "width": 340,
        "color": 6
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000002",
      "name": "Sticky: Product Path Label",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        560,
        320
      ]
    },
    {
      "parameters": {
        "content": "## Agent 1: Classification\n**Tool:** Regulatory taxonomy lookup\n**Used when:** Only when the narrative is ambiguous relative to the filed category",
        "height": 160,
        "width": 260,
        "color": 6
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000003",
      "name": "Sticky: Agent 1 Role Card",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1180,
        210
      ]
    },
    {
      "parameters": {
        "content": "## Agent 2: Research\n**Tool:** Synthetic CRM lookup + regulation-text lookup\n**Used when:** Regulation lookup always; special-population check always; broader CRM context only when relevant",
        "height": 160,
        "width": 260,
        "color": 6
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000004",
      "name": "Sticky: Agent 2 Role Card",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1860,
        210
      ]
    },
    {
      "parameters": {
        "content": "## Agent 3: Drafting\n**Tool:** Exact regulation clause fetch\n**Used when:** Only when citing a specific provision",
        "height": 160,
        "width": 260,
        "color": 6
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000005",
      "name": "Sticky: Agent 3 Role Card",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2960,
        210
      ]
    },
    {
      "parameters": {
        "content": "## Agent 4: QA / escalation-scoring\n**Tool:** Re-verify a cited clause or CRM fact\n**Used when:** Only when the draft makes a checkable claim",
        "height": 160,
        "width": 260,
        "color": 6
      },
      "id": "c3a8e4b2-0002-4000-8000-000000000006",
      "name": "Sticky: Agent 4 Role Card",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        3620,
        210
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Agent 1: Classification -- MOCKED reasoning layer (spec Section 15 Phase 3).\n// Returns the literal Section 6 fixture output for Tickets A/B/C. The tool\n// this agent conditionally calls (taxonomy lookup) is real -- see the next\n// node -- only the classification judgment itself is mocked here.\nconst AGENT1_FIXTURES = {\n  \"9999970\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"issue\": \"Written notification about debt\",\n      \"severity\": \"High\",\n      \"confidence\": 0.88\n    }\n  },\n  \"9999975\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"issue\": \"Attempts to collect debt not owed\",\n      \"severity\": \"High\",\n      \"confidence\": 0.81\n    }\n  },\n  \"9999983\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"issues\": [\n        {\n          \"issue\": \"Card opened without my consent or knowledge\",\n          \"severity\": \"High\",\n          \"confidence\": 0.78,\n          \"basis\": \"Consumer's own filed CFPB category; narrative references a 'fraudulent case application'\"\n        },\n        {\n          \"issue\": \"Service failure \u2014 dropped call, no follow-up\",\n          \"severity\": \"Low\",\n          \"confidence\": 0.9,\n          \"basis\": \"Explicitly described in narrative\"\n        }\n      ],\n      \"primary_issue\": \"Card opened without my consent or knowledge\"\n    }\n  },\n  \"24157195\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"issue\": \"Attempts to collect debt not owed\",\n      \"severity\": \"Low\",\n      \"confidence\": 0.85\n    }\n  },\n  \"24157200\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"issue\": \"Trouble using your card\",\n      \"severity\": \"Medium\",\n      \"confidence\": 0.7\n    }\n  },\n  \"24157240\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"issue\": \"Attempts to collect debt not owed\",\n      \"severity\": \"Low\",\n      \"confidence\": 0.82\n    }\n  },\n  \"24157473\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"issue\": \"Fees or interest\",\n      \"severity\": \"Medium\",\n      \"confidence\": 0.72\n    }\n  },\n  \"24157609\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"issue\": \"Attempts to collect debt not owed\",\n      \"severity\": \"High\",\n      \"confidence\": 0.6\n    }\n  },\n  \"24157871\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"issue\": \"Communication tactics\",\n      \"severity\": \"High\",\n      \"confidence\": 0.8\n    }\n  },\n  \"24158082\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"issue\": \"Written notification about debt\",\n      \"severity\": \"High\",\n      \"confidence\": 0.83\n    }\n  }\n};\n\nconst ticket = $input.item.json;\nconst fixture = AGENT1_FIXTURES[String(ticket.complaint_id)];\nif (!fixture) {\n  return { json: { ...ticket, _mock_unavailable: true, agent1_tool_used: false, agent1_output: null } };\n}\nreturn { json: { ...ticket, agent1_tool_used: fixture.tool_used, agent1_output: fixture.output } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000006",
      "name": "Agent 1: Mock Classification Decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1180,
        -140
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-000000000007-cond",
              "leftValue": "={{ $json.agent1_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000007",
      "name": "IF: Agent 1 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1400,
        -140
      ],
      "notesInFlow": true,
      "notes": "Conditional tool-use, made visible: Agent 1 only calls the taxonomy lookup when the narrative is ambiguous relative to the filed category (spec Section 6). Clean-match tickets (A, B) skip it."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 1 (real): CFPB product/issue/sub-issue taxonomy lookup -- the same\n// cached snapshot as reference_data/taxonomy/cfpb_taxonomy.json (Phase 1).\n// Searches both issue- and sub-issue-level names, since Agent 1's\n// classification may hand back either.\nconst TAXONOMY = {\"_meta\":{\"description\":\"CFPB Consumer Complaint Database product/issue/sub-issue taxonomy, scoped to the S2.3 pilot categories (Debt collection, Credit card). Backs Agent 1 (Classification)'s taxonomy lookup tool -- spec Section 6.\",\"source\":\"https://www.consumerfinance.gov/data-research/consumer-complaints/search/api/v1/ (live aggregations query, no auth required)\",\"retrieved_date\":\"2026-08-12\",\"scope_note\":\"Pulled once at build time per spec Section 6 / Section 15 Phase 1 -- cached static lookup, not re-fetched per ticket.\"},\"products\":[{\"product\":\"Debt collection\",\"total_complaints_in_scope\":1167638,\"sub_products\":[{\"name\":\"I do not know\",\"doc_count\":474297},{\"name\":\"Other debt\",\"doc_count\":195980},{\"name\":\"Credit card debt\",\"doc_count\":177098},{\"name\":\"Medical debt\",\"doc_count\":76913},{\"name\":\"Other (i.e. phone, health club, etc.)\",\"doc_count\":44436},{\"name\":\"Auto debt\",\"doc_count\":32099},{\"name\":\"Telecommunications debt\",\"doc_count\":30154},{\"name\":\"Credit card\",\"doc_count\":28626},{\"name\":\"Rental debt\",\"doc_count\":28622},{\"name\":\"Medical\",\"doc_count\":21143},{\"name\":\"Payday loan debt\",\"doc_count\":16325},{\"name\":\"Mortgage debt\",\"doc_count\":8496},{\"name\":\"Payday loan\",\"doc_count\":7493},{\"name\":\"Private student loan debt\",\"doc_count\":6058},{\"name\":\"Federal student loan debt\",\"doc_count\":5992},{\"name\":\"Mortgage\",\"doc_count\":4807},{\"name\":\"Auto\",\"doc_count\":3748},{\"name\":\"Non-federal student loan\",\"doc_count\":2878},{\"name\":\"Federal student loan\",\"doc_count\":2473}],\"issues\":[{\"name\":\"Attempts to collect debt not owed\",\"doc_count\":469041,\"sub_issues\":[{\"name\":\"Debt is not yours\",\"doc_count\":262452},{\"name\":\"Debt was result of identity theft\",\"doc_count\":139468},{\"name\":\"Debt was paid\",\"doc_count\":54398},{\"name\":\"Debt was already discharged in bankruptcy and is no longer owed\",\"doc_count\":12723}]},{\"name\":\"Written notification about debt\",\"doc_count\":226489,\"sub_issues\":[{\"name\":\"Didn't receive enough information to verify debt\",\"doc_count\":114695},{\"name\":\"Notification didn't disclose it was an attempt to collect a debt\",\"doc_count\":62578},{\"name\":\"Didn't receive notice of right to dispute\",\"doc_count\":49216}]},{\"name\":\"Took or threatened to take negative or legal action\",\"doc_count\":143350,\"sub_issues\":[{\"name\":\"Threatened or suggested your credit would be damaged\",\"doc_count\":111195},{\"name\":\"Threatened to sue you for very old debt\",\"doc_count\":11131},{\"name\":\"Sued you without properly notifying you of lawsuit\",\"doc_count\":7534},{\"name\":\"Seized or attempted to seize your property\",\"doc_count\":5239},{\"name\":\"Threatened to arrest you or take you to jail if you do not pay\",\"doc_count\":3496},{\"name\":\"Collected or attempted to collect exempt funds\",\"doc_count\":3037},{\"name\":\"Sued you in a state where you do not live or did not sign for the debt\",\"doc_count\":1462},{\"name\":\"Threatened to turn you in to immigration or deport you\",\"doc_count\":256}]},{\"name\":\"False statements or representation\",\"doc_count\":118634,\"sub_issues\":[{\"name\":\"Attempted to collect wrong amount\",\"doc_count\":104998},{\"name\":\"Impersonated attorney, law enforcement, or government official\",\"doc_count\":6304},{\"name\":\"Indicated you were committing crime by not paying debt\",\"doc_count\":3456},{\"name\":\"Impersonated an attorney or official\",\"doc_count\":1284},{\"name\":\"Told you not to respond to a lawsuit they filed against you\",\"doc_count\":1235},{\"name\":\"Indicated committed crime not paying\",\"doc_count\":1012},{\"name\":\"Indicated shouldn't respond to lawsuit\",\"doc_count\":345}]},{\"name\":\"Communication tactics\",\"doc_count\":77065,\"sub_issues\":[{\"name\":\"Frequent or repeated calls\",\"doc_count\":42329},{\"name\":\"You told them to stop contacting you, but they keep trying\",\"doc_count\":16978},{\"name\":\"Used obscene, profane, or other abusive language\",\"doc_count\":6111},{\"name\":\"Threatened to take legal action\",\"doc_count\":4669},{\"name\":\"Called before 8am or after 9pm\",\"doc_count\":2374},{\"name\":\"Called after sent written cease of comm\",\"doc_count\":1852},{\"name\":\"Used obscene/profane/abusive language\",\"doc_count\":1832},{\"name\":\"Called outside of 8am-9pm\",\"doc_count\":912},{\"name\":\"Frequent or repeated messages\",\"doc_count\":4},{\"name\":\"Contacted before 8am or after 9pm\",\"doc_count\":3}]},{\"name\":\"Cont'd attempts collect debt not owed\",\"doc_count\":60520,\"sub_issues\":[{\"name\":\"Debt is not mine\",\"doc_count\":36629},{\"name\":\"Debt was paid\",\"doc_count\":16582},{\"name\":\"Debt resulted from identity theft\",\"doc_count\":4899},{\"name\":\"Debt was discharged in bankruptcy\",\"doc_count\":2410}]},{\"name\":\"Disclosure verification of debt\",\"doc_count\":30728,\"sub_issues\":[{\"name\":\"Not given enough info to verify debt\",\"doc_count\":21757},{\"name\":\"Right to dispute notice not received\",\"doc_count\":7174},{\"name\":\"Not disclosed as an attempt to collect\",\"doc_count\":1797}]},{\"name\":\"Threatened to contact someone or share information improperly\",\"doc_count\":13300,\"sub_issues\":[{\"name\":\"Talked to a third-party about your debt\",\"doc_count\":7634},{\"name\":\"Contacted you after you asked them to stop\",\"doc_count\":2985},{\"name\":\"Contacted your employer\",\"doc_count\":2482},{\"name\":\"Contacted you instead of your attorney\",\"doc_count\":199}]},{\"name\":\"Improper contact or sharing of info\",\"doc_count\":10036,\"sub_issues\":[{\"name\":\"Talked to a third party about my debt\",\"doc_count\":5037},{\"name\":\"Contacted me after I asked not to\",\"doc_count\":2567},{\"name\":\"Contacted employer after asked not to\",\"doc_count\":2192},{\"name\":\"Contacted me instead of my attorney\",\"doc_count\":240}]},{\"name\":\"Electronic communications\",\"doc_count\":9682,\"sub_issues\":[{\"name\":\"Frequent or repeated messages\",\"doc_count\":5850},{\"name\":\"You told them to stop contacting you, but they keep trying\",\"doc_count\":2884},{\"name\":\"Contacted before 8am or after 9pm\",\"doc_count\":680},{\"name\":\"Used obscene, profane, or other abusive language\",\"doc_count\":268}]},{\"name\":\"Taking/threatening an illegal action\",\"doc_count\":8793,\"sub_issues\":[{\"name\":\"Threatened to sue on too old debt\",\"doc_count\":2690},{\"name\":\"Threatened arrest/jail if do not pay\",\"doc_count\":2253},{\"name\":\"Sued w/o proper notification of suit\",\"doc_count\":1387},{\"name\":\"Seized/Attempted to seize property\",\"doc_count\":1159},{\"name\":\"Attempted to/Collected exempt funds\",\"doc_count\":903},{\"name\":\"Sued where didn't live/sign for debt\",\"doc_count\":401}]}]},{\"product\":\"Credit card\",\"total_complaints_in_scope\":333515,\"sub_products\":[{\"name\":\"General-purpose credit card or charge card\",\"doc_count\":217513},{\"name\":\"Store credit card\",\"doc_count\":26817}],\"issues\":[{\"name\":\"Problem with a purchase shown on your statement\",\"doc_count\":57864,\"sub_issues\":[{\"name\":\"Credit card company isn't resolving a dispute about a purchase on your statement\",\"doc_count\":43435},{\"name\":\"Card was charged for something you did not purchase with the card\",\"doc_count\":12841},{\"name\":\"Overcharged for something you did purchase with the card\",\"doc_count\":1588}]},{\"name\":\"Incorrect information on your report\",\"doc_count\":31970,\"sub_issues\":[{\"name\":\"Account status incorrect\",\"doc_count\":23892},{\"name\":\"Account information incorrect\",\"doc_count\":3687},{\"name\":\"Information belongs to someone else\",\"doc_count\":3368},{\"name\":\"Old information reappears or never goes away\",\"doc_count\":401},{\"name\":\"Information is missing that should be on the report\",\"doc_count\":234},{\"name\":\"Personal information incorrect\",\"doc_count\":213},{\"name\":\"Public record information inaccurate\",\"doc_count\":175}]},{\"name\":\"Getting a credit card\",\"doc_count\":30200,\"sub_issues\":[{\"name\":\"Card opened without my consent or knowledge\",\"doc_count\":20460},{\"name\":\"Application denied\",\"doc_count\":6209},{\"name\":\"Sent card you never applied for\",\"doc_count\":1428},{\"name\":\"Delay in processing application\",\"doc_count\":1131},{\"name\":\"Problem getting a working replacement card\",\"doc_count\":972}]},{\"name\":\"Problem with a company's investigation into an existing problem\",\"doc_count\":26306,\"sub_issues\":[{\"name\":\"Was not notified of investigation status or results\",\"doc_count\":20284},{\"name\":\"Their investigation did not fix an error on your report\",\"doc_count\":4654},{\"name\":\"Problem with personal statement of dispute\",\"doc_count\":626},{\"name\":\"Difficulty submitting a dispute or getting information about a dispute over the phone\",\"doc_count\":507},{\"name\":\"Investigation took more than 30 days\",\"doc_count\":235}]},{\"name\":\"Other features, terms, or problems\",\"doc_count\":24417,\"sub_issues\":[{\"name\":\"Other problem\",\"doc_count\":12042},{\"name\":\"Problem with rewards from credit card\",\"doc_count\":5515},{\"name\":\"Problem with customer service\",\"doc_count\":2514},{\"name\":\"Problem with balance transfer\",\"doc_count\":1574},{\"name\":\"Privacy issues\",\"doc_count\":1558},{\"name\":\"Add-on products and services\",\"doc_count\":580},{\"name\":\"Credit card company forcing arbitration\",\"doc_count\":309},{\"name\":\"Problem with cash advances\",\"doc_count\":239},{\"name\":\"Problem with convenience check\",\"doc_count\":86}]},{\"name\":\"Fees or interest\",\"doc_count\":21692,\"sub_issues\":[{\"name\":\"Problem with fees\",\"doc_count\":13275},{\"name\":\"Charged too much interest\",\"doc_count\":6273},{\"name\":\"Unexpected increase in interest rate\",\"doc_count\":2144}]},{\"name\":\"Closing your account\",\"doc_count\":15397,\"sub_issues\":[{\"name\":\"Company closed your account\",\"doc_count\":11972},{\"name\":\"Can't close your account\",\"doc_count\":3425}]},{\"name\":\"Billing disputes\",\"doc_count\":15136,\"sub_issues\":[]},{\"name\":\"Problem when making payments\",\"doc_count\":12937,\"sub_issues\":[{\"name\":\"Problem during payment process\",\"doc_count\":11227},{\"name\":\"You never received your bill or did not know a payment was due\",\"doc_count\":1710}]},{\"name\":\"Other\",\"doc_count\":9350,\"sub_issues\":[]},{\"name\":\"Advertising and marketing, including promotional offers\",\"doc_count\":9134,\"sub_issues\":[{\"name\":\"Didn't receive advertised or promotional terms\",\"doc_count\":5112},{\"name\":\"Confusing or misleading advertising about the credit card\",\"doc_count\":4022}]},{\"name\":\"Identity theft / Fraud / Embezzlement\",\"doc_count\":8480,\"sub_issues\":[]},{\"name\":\"Trouble using your card\",\"doc_count\":8174,\"sub_issues\":[{\"name\":\"Can't use card to make purchases\",\"doc_count\":5530},{\"name\":\"Credit card company won't increase or decrease your credit limit\",\"doc_count\":2485},{\"name\":\"Account sold or transferred to another company\",\"doc_count\":159}]},{\"name\":\"Closing/Cancelling account\",\"doc_count\":6389,\"sub_issues\":[]},{\"name\":\"APR or interest rate\",\"doc_count\":5506,\"sub_issues\":[]},{\"name\":\"Late fee\",\"doc_count\":3639,\"sub_issues\":[]},{\"name\":\"Customer service / Customer relations\",\"doc_count\":3504,\"sub_issues\":[]},{\"name\":\"Delinquent account\",\"doc_count\":3218,\"sub_issues\":[]},{\"name\":\"Struggling to pay your bill\",\"doc_count\":3079,\"sub_issues\":[{\"name\":\"Credit card company won't work with you while you're going through financial hardship\",\"doc_count\":2681},{\"name\":\"Problem lowering your monthly payments\",\"doc_count\":248},{\"name\":\"Filed for bankruptcy\",\"doc_count\":150}]},{\"name\":\"Credit determination\",\"doc_count\":3057,\"sub_issues\":[]},{\"name\":\"Advertising and marketing\",\"doc_count\":2926,\"sub_issues\":[]},{\"name\":\"Rewards\",\"doc_count\":2916,\"sub_issues\":[]},{\"name\":\"Credit card protection / Debt protection\",\"doc_count\":2728,\"sub_issues\":[]},{\"name\":\"Transaction issue\",\"doc_count\":2700,\"sub_issues\":[]},{\"name\":\"Billing statement\",\"doc_count\":2619,\"sub_issues\":[]},{\"name\":\"Payoff process\",\"doc_count\":2315,\"sub_issues\":[]},{\"name\":\"Improper use of your report\",\"doc_count\":2263,\"sub_issues\":[{\"name\":\"Reporting company used your report improperly\",\"doc_count\":1379},{\"name\":\"Credit inquiries on your report that you don't recognize\",\"doc_count\":837},{\"name\":\"Received unsolicited financial product or insurance offers after opting out\",\"doc_count\":24},{\"name\":\"Report provided to employer without your written authorization\",\"doc_count\":23}]},{\"name\":\"Other fee\",\"doc_count\":2198,\"sub_issues\":[]},{\"name\":\"Credit line increase/decrease\",\"doc_count\":2185,\"sub_issues\":[]},{\"name\":\"Unsolicited issuance of credit card\",\"doc_count\":1853,\"sub_issues\":[]},{\"name\":\"Credit reporting\",\"doc_count\":1696,\"sub_issues\":[]},{\"name\":\"Balance transfer\",\"doc_count\":1117,\"sub_issues\":[]},{\"name\":\"Collection practices\",\"doc_count\":1001,\"sub_issues\":[]},{\"name\":\"Collection debt dispute\",\"doc_count\":901,\"sub_issues\":[]},{\"name\":\"Forbearance / Workout plans\",\"doc_count\":556,\"sub_issues\":[]},{\"name\":\"Credit monitoring or identity theft protection services\",\"doc_count\":547,\"sub_issues\":[{\"name\":\"Billing dispute for services\",\"doc_count\":245},{\"name\":\"Problem canceling credit monitoring or identify theft protection service\",\"doc_count\":165},{\"name\":\"Didn't receive services that were advertised\",\"doc_count\":63},{\"name\":\"Problem with product or service terms changing\",\"doc_count\":52},{\"name\":\"Received unwanted marketing or advertising\",\"doc_count\":22}]},{\"name\":\"Application processing delay\",\"doc_count\":540,\"sub_issues\":[]},{\"name\":\"Privacy\",\"doc_count\":489,\"sub_issues\":[]},{\"name\":\"Bankruptcy\",\"doc_count\":448,\"sub_issues\":[]},{\"name\":\"Arbitration\",\"doc_count\":348,\"sub_issues\":[]},{\"name\":\"Sale of account\",\"doc_count\":344,\"sub_issues\":[]},{\"name\":\"Cash advance\",\"doc_count\":245,\"sub_issues\":[]},{\"name\":\"Problem with fraud alerts or security freezes\",\"doc_count\":234,\"sub_issues\":[]},{\"name\":\"Balance transfer fee\",\"doc_count\":221,\"sub_issues\":[]},{\"name\":\"Overlimit fee\",\"doc_count\":215,\"sub_issues\":[]},{\"name\":\"Cash advance fee\",\"doc_count\":196,\"sub_issues\":[]},{\"name\":\"Convenience checks\",\"doc_count\":149,\"sub_issues\":[]},{\"name\":\"Unable to get your credit report or credit score\",\"doc_count\":116,\"sub_issues\":[{\"name\":\"Other problem getting your report or credit score\",\"doc_count\":113},{\"name\":\"Problem getting your free annual credit report\",\"doc_count\":3}]}]}]};\n\nfunction taxonomyLookup(taxonomy, product, categoryName) {\r\n  const productEntry = taxonomy.products.find((p) => p.product === product);\r\n  if (!productEntry) return { found: false, note: `Product '${product}' not in cached taxonomy scope.` };\r\n\r\n  const issueEntry = productEntry.issues.find((i) => i.name === categoryName);\r\n  if (issueEntry) {\r\n    return { found: true, level: \"issue\", issue: issueEntry.name, doc_count: issueEntry.doc_count, sibling_sub_issues: issueEntry.sub_issues.map((s) => s.name) };\r\n  }\r\n\r\n  for (const issue of productEntry.issues) {\r\n    const subIssueEntry = issue.sub_issues.find((s) => s.name === categoryName);\r\n    if (subIssueEntry) {\r\n      return {\r\n        found: true, level: \"sub_issue\", parent_issue: issue.name, sub_issue: subIssueEntry.name,\r\n        doc_count: subIssueEntry.doc_count,\r\n        sibling_sub_issues: issue.sub_issues.map((s) => s.name).filter((n) => n !== categoryName),\r\n      };\r\n    }\r\n  }\r\n\r\n  return { found: false, note: `'${categoryName}' not found as an issue or sub-issue under product '${product}'.` };\r\n}\n\nconst ticket = $input.item.json;\nconst category = (ticket.agent1_output && (ticket.agent1_output.primary_issue || ticket.agent1_output.issue)) || ticket.issue;\nconst result = taxonomyLookup(TAXONOMY, ticket.product, category);\nreturn { json: { ...ticket, agent1_tool_result: result } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000008",
      "name": "Tool: CFPB Taxonomy Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1620,
        -260
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001c",
      "name": "Merge: Pre-Agent 2",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        1720,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Agent 2: Research -- MOCKED reasoning layer. Per spec v5, the broader CRM\n// lookup (tenure/balance/prior-complaint history) is discretionary -- this\n// node's fixture table encodes that per-ticket decision. special_population_flag\n// and the regulation-index tool are handled in separate always-run nodes\n// downstream, per spec v5's structured hand-off design.\nconst AGENT2_FIXTURES = {\n  \"9999970\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": \"FDCPA \u00a7809(b)\",\n      \"citation\": \"15 U.S.C. \u00a71692g(b)\",\n      \"precedent_notes\": \"30-day validation claim consistent with FDCPA; servicemember status raises SCRA considerations\"\n    }\n  },\n  \"9999975\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": \"FCRA \u00a7605B + FDCPA \u00a7807\",\n      \"citation\": \"15 U.S.C. \u00a71681c-2; \u00a71692e\",\n      \"precedent_notes\": \"Pattern matches identity-theft profile, not a routine amount dispute\"\n    }\n  },\n  \"9999983\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"customer_context\": \"tenure 3yrs, 2 products, 0 prior complaints \u2014 no pattern of repeat unauthorised-account claims\",\n      \"applicable_regulation\": \"FCRA \u00a7605B identity-theft block procedure\",\n      \"citation\": \"15 U.S.C. \u00a71681c-2\",\n      \"precedent_notes\": \"Filed category plus 'fraudulent case application' language point to the account-opening issue as substantive; the dropped call compounds it, doesn't replace it\"\n    }\n  },\n  \"24157195\": {\n    \"broader_crm_lookup_used\": false,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search (issue + narrative -- there is no narrative) returned zero matches. A generic 'not my debt' dispute with a clean CRM (0 prior complaints, no special-population flag) doesn't warrant the discretionary broader-context lookup.\"\n    }\n  },\n  \"24157200\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search returned zero matches -- FCRA's adverse-action disclosure requirement (15 U.S.C. \u00a71681m) isn't in this build's cached corpus (only \u00a71681c-2's identity-theft block procedure is). CRM shows 2 prior complaints in the past 12 months, an independent repeat-complainant signal regardless.\"\n    }\n  },\n  \"24157240\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search (issue + narrative -- there is no narrative) returned zero matches. Broader CRM context pulled given the dispute nature: tenure 1yr, single Checking Account holding, 0 prior complaints, 0 prior contacts in 90 days -- no pattern of repeat 'not mine' disputes or account friction.\"\n    }\n  },\n  \"24157473\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search returned zero matches -- the consumer's claim rests on Massachusetts General Laws c. 140 \u00a7114C, a state statute this build's five-regulation federal corpus was never scoped to cover (spec Section 4).\"\n    }\n  },\n  \"24157609\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search (issue + narrative only -- there is no narrative for this ticket) returned zero matches. CFPB's own filed sub-issue is 'Debt was result of identity theft', a real and serious label, but this build's regulation-search tool deliberately doesn't see sub-issue text (the same reasoning as the Ticket C taxonomy-sibling finding: trust the structured classification pipeline, not surface wording), so no citation is available to hand to Agent 3.\"\n    }\n  },\n  \"24157871\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": null,\n      \"citation\": null,\n      \"precedent_notes\": \"Real regulation-index search (issue + narrative, no matching terms) returned zero matches -- FDCPA \u00a71692d (harassment/abuse) isn't in this build's cached corpus (only \u00a71692g and \u00a71692e are). Escalation instead rests on the contact-frequency pattern itself and the consumer's already-paid claim, not a citation.\"\n    }\n  },\n  \"24158082\": {\n    \"broader_crm_lookup_used\": true,\n    \"output\": {\n      \"applicable_regulation\": \"FDCPA \u00a7809(b)\",\n      \"citation\": \"15 U.S.C. \u00a71692g(b)\",\n      \"precedent_notes\": \"Real regulation-index search matched 'validation' directly out of the consumer's own narrative text against the cached FDCPA \u00a71692g entry. CRM shows 3 prior complaints in the past 12 months \u2014 an independent repeat-complainant signal separate from this ticket's own substance.\"\n    }\n  }\n};\n\nconst ticket = $input.item.json;\nconst fixture = AGENT2_FIXTURES[String(ticket.complaint_id)];\nif (!fixture) {\n  return { json: { ...ticket, _mock_unavailable: true, agent2_broader_crm_lookup_used: false, agent2_output: null } };\n}\nreturn { json: { ...ticket, agent2_broader_crm_lookup_used: fixture.broader_crm_lookup_used, agent2_output: fixture.output } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000009",
      "name": "Agent 2: Mock Research Decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1840,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2, tier 1 (real, always runs -- spec v5): a deterministic yes/no read\n// off the CRM record, not a judgment call, so it is exempted from Agent 2's\n// usual discretion and checked on every ticket. Carried as its own structured\n// field so Agent 4 reads it as data, not buried in free-text customer_context.\nconst ticket = $input.item.json;\nconst special_population_flag = Boolean(ticket.crm.special_population_flag);\nreturn {\n  json: {\n    ...ticket,\n    agent2_special_population_flag: special_population_flag,\n    agent2_output: { ...ticket.agent2_output, special_population_flag },\n  },\n};"
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000a",
      "name": "Tool: Special Population Check",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2060,
        -140
      ],
      "notesInFlow": true,
      "notes": "Always runs, every ticket (spec v5) -- deterministic, not discretionary."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2, tier 2 (real, always runs -- spec Section 6: \"(b) always, based on\n// classification\"). Keyword + light synonym search across the cached\n// regulation corpus' topics (reference_data/regulations/*.json _meta) to\n// surface candidate applicable regulations. This is deliberately a simple,\n// deterministic lookup, not semantic search -- see README for the honest\n// limitation this implies.\nconst REGULATION_META_INDEX = {\n  \"fdcpa_1692g\": {\n    \"regulation\": \"FDCPA\",\n    \"citation\": \"15 U.S.C. \u00a71692g\",\n    \"topic\": \"Debt validation notice\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1692g\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"fdcpa_1692e\": {\n    \"regulation\": \"FDCPA\",\n    \"citation\": \"15 U.S.C. \u00a71692e\",\n    \"topic\": \"False or misleading representations\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1692e\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"fcra_1681c-2\": {\n    \"regulation\": \"FCRA\",\n    \"citation\": \"15 U.S.C. \u00a71681c-2\",\n    \"topic\": \"Identity-theft block procedure\",\n    \"source_url\": \"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"reg_z_1026_13\": {\n    \"regulation\": \"Regulation Z (FCBA)\",\n    \"citation\": \"12 CFR \u00a71026.13\",\n    \"topic\": \"Billing-error resolution procedure\",\n    \"source_url\": \"https://www.law.cornell.edu/cfr/text/12/1026.13\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\n    \"sourcing_note\": \"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"\n  },\n  \"cfpb_15day_rule\": {\n    \"regulation\": \"CFPB complaint rule\",\n    \"citation\": \"Dodd-Frank Act company-response standard\",\n    \"topic\": \"Company response deadline\",\n    \"source_url\": \"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\n    \"retrieved_date\": \"2026-08-12\",\n    \"pilot_relevance\": \"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\n    \"sourcing_note\": \"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"\n  }\n};\nconst REGULATION_SEARCH_STOPWORDS = new Set([\"debt\",\"debts\",\"credit\",\"card\",\"cards\",\"collection\",\"collector\",\"consumer\",\"consumers\",\"company\",\"companies\",\"account\",\"accounts\",\"with\",\"that\",\"this\",\"from\",\"were\",\"have\",\"been\",\"into\",\"about\",\"attempts\",\"review\",\"reviewed\",\"found\",\"believe\",\"believed\"]);\nconst REGULATION_SEARCH_SYNONYMS = {\"fraud\":\"identity-theft\",\"fraudulent\":\"identity-theft\",\"identity\":\"identity-theft\",\"theft\":\"identity-theft\",\"unauthorized\":\"identity-theft\",\"stolen\":\"identity-theft\",\"false\":\"misleading\",\"deceptive\":\"misleading\",\"misrepresentation\":\"misleading\",\"wrong\":\"billing-error\",\"incorrect\":\"billing-error\",\"error\":\"billing-error\",\"validate\":\"validation\",\"validating\":\"validation\"};\nconst REGULATION_SEARCH_PHRASE_SYNONYMS = [\n  {\n    \"phrases\": [\n      \"fraudulent\",\n      \"not mine\",\n      \"don't recognize\",\n      \"do not recognize\",\n      \"identity theft\",\n      \"unauthorized\"\n    ],\n    \"addsTerm\": \"identity-theft\"\n  },\n  {\n    \"phrases\": [\n      \"didn't receive\",\n      \"did not receive\",\n      \"never received\",\n      \"never got\",\n      \"never sent\",\n      \"no notice\",\n      \"without notice\"\n    ],\n    \"addsTerm\": \"validation\"\n  }\n];\n\nfunction regulationIndexLookup(regulationMetaIndex, stopwords, synonyms, phraseSynonyms, queryText) {\r\n  const lowerQuery = queryText.toLowerCase();\r\n  const rawTerms = lowerQuery.split(/[^a-z-]+/).filter((t) => t.length > 4 && !stopwords.has(t));\r\n  const tokenTerms = rawTerms.flatMap((t) => [t, synonyms[t]].filter(Boolean));\r\n  const phraseTerms = phraseSynonyms.filter((ps) => ps.phrases.some((p) => lowerQuery.includes(p))).map((ps) => ps.addsTerm);\r\n  const terms = [...new Set([...tokenTerms, ...phraseTerms])];\r\n  const matches = [];\r\n  for (const [id, meta] of Object.entries(regulationMetaIndex)) {\r\n    const haystack = meta.topic.toLowerCase();\r\n    const hit = terms.filter((t) => haystack.includes(t));\r\n    if (hit.length > 0) matches.push({ id, citation: meta.citation, topic: meta.topic, matched_terms: hit });\r\n  }\r\n  return matches;\r\n}\n\nconst ticket = $input.item.json;\nconst category = (ticket.agent1_output && (ticket.agent1_output.primary_issue || ticket.agent1_output.issue)) || ticket.issue;\nconst queryText = `${ticket.issue} ${category} ${ticket.complaint_what_happened || \"\"}`;\nconst result = regulationIndexLookup(REGULATION_META_INDEX, REGULATION_SEARCH_STOPWORDS, REGULATION_SEARCH_SYNONYMS, REGULATION_SEARCH_PHRASE_SYNONYMS, queryText);\nreturn { json: { ...ticket, agent2_regulation_tool_result: result } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000b",
      "name": "Tool: Regulation Index Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2280,
        -140
      ],
      "notesInFlow": true,
      "notes": "Always runs, based on classification (spec Section 6)."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-00000000000c-cond",
              "leftValue": "={{ $json.agent2_broader_crm_lookup_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000c",
      "name": "IF: Agent 2 Broader CRM Lookup Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2500,
        -140
      ],
      "notesInFlow": true,
      "notes": "Discretionary tier (spec v5): tenure/balance/prior-complaint context, only pulled when relevant. Known gap: all three Phase 3 fixtures warrant this lookup, so the false branch is structurally present but untested here -- spec's own flagged Phase 7 verification item."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 2a (real, discretionary -- spec Section 6): the broader CRM context\n// pull (tenure, tier, holdings, balance, prior complaints), gated on Agent\n// 2's mock decision. Reads directly off the synthetic CRM record (Phase 2) --\n// no separate lookup needed, the record already travels with the ticket.\nconst ticket = $input.item.json;\nconst crm = ticket.crm;\nreturn {\n  json: {\n    ...ticket,\n    agent2_crm_tool_result: {\n      tenure_years: crm.tenure_years,\n      account_tier: crm.account_tier,\n      product_holdings: crm.product_holdings,\n      outstanding_balance_usd: crm.outstanding_balance_usd,\n      prior_complaints_12mo: crm.prior_complaints_12mo,\n    },\n  },\n};"
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000d",
      "name": "Tool: CRM Broader Context Lookup",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2720,
        -260
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001d",
      "name": "Merge: Pre-Agent 3",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        2820,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Agent 3: Drafting -- MOCKED reasoning layer. Returns the literal Section 6\n// fixture draft. cited_clause records which citation the exact-clause-fetch\n// tool should retrieve for this ticket (the real work happens in the next node).\nconst AGENT3_FIXTURES = {\n  \"9999970\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"draft\": \"Cites \u00a71692g(b), commits to resending itemised validation documentation, pauses collection activity\",\n      \"cites_regulation\": true\n    },\n    \"cited_clause\": \"15 U.S.C. \u00a71692g(b)\"\n  },\n  \"9999975\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"draft\": \"Provides FTC identity-theft report/police report instructions per \u00a7605B, confirms collection paused\",\n      \"cites_regulation\": true\n    },\n    \"cited_clause\": \"15 U.S.C. \u00a71681c-2\"\n  },\n  \"9999983\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"draft\": \"Apologises for the dropped call and commits to a 24hr callback; separately and primarily, treats the account-opening concern as a potential unauthorised-account matter, provides FCRA \u00a7605B block-request instructions, confirms no charges apply pending investigation\",\n      \"cites_regulation\": true\n    },\n    \"cited_clause\": \"15 U.S.C. \u00a71681c-2\"\n  },\n  \"24157195\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Sends the standard debt-validation request acknowledgment: confirms the dispute is logged, and requests the company either substantiate the debt with account-level proof or close the collection action\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24157200\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Acknowledges the consumer's itemised list of missing FCRA adverse-action disclosures and commits to an internal compliance review of the credit-limit denial letter template\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24157240\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Sends the standard debt-validation request acknowledgment: confirms the dispute is logged, and requests the company either substantiate the debt with account-level proof or close the collection action\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24157473\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Acknowledges the consumer's cited Massachusetts General Laws c. 140 \u00a7114C pro-rated fee-refund claim and the $400 annual fee at issue; recommends routing to a state-compliance specialist since no federal regulation in the cached index applies\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24157609\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Acknowledges the account is disputed as resulting from identity theft per the consumer's own filed CFPB category, and requests supporting documentation (a police report or FTC identity-theft report) before proceeding\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24157871\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"draft\": \"Acknowledges the excessive-contact pattern (9 calls, 8 voicemails in 7 minutes) and the consumer's claim the debt was already paid; commits to pausing outbound contact pending an internal payment-history review\",\n      \"cites_regulation\": false\n    }\n  },\n  \"24158082\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"draft\": \"Cites \u00a71692g(b), pauses collection activity pending validation, requests the company produce a full accounting and proof of the outstanding balance given the consumer's $0-balance receipt and the stale mailing address\",\n      \"cites_regulation\": true\n    },\n    \"cited_clause\": \"15 U.S.C. \u00a71692g(b)\"\n  }\n};\n\nconst ticket = $input.item.json;\nconst fixture = AGENT3_FIXTURES[String(ticket.complaint_id)];\nif (!fixture) {\n  return { json: { ...ticket, _mock_unavailable: true, agent3_tool_used: false, agent3_output: null } };\n}\nreturn { json: { ...ticket, agent3_tool_used: fixture.tool_used, agent3_output: fixture.output, _agent3_cited_clause: fixture.cited_clause } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000e",
      "name": "Agent 3: Mock Drafting Decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2940,
        -140
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-00000000000f-cond",
              "leftValue": "={{ $json.agent3_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000000f",
      "name": "IF: Agent 3 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3160,
        -140
      ],
      "notesInFlow": true,
      "notes": "Only when citing a specific provision (spec Section 6). Untested false branch: all three fixtures cite a regulation."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 3 (real): exact regulation clause fetch -- parses a citation like\n// \"15 U.S.C. \u00a71692g(b)\" and extracts just that lettered subsection from the\n// cached verbatim regulation text (reference_data/regulations/*.json). Falls\n// back to the full section text when the citation doesn't name a subsection.\nconst REGULATIONS = {\"fdcpa_1692g\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692g\",\"topic\":\"Debt validation notice\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692g\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692g - Validation of debts\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Notice of debt; contents Within five days after the initial communication with a consumer in connection with the collection of any debt, a debt collector shall, unless the following information is contained in the initial communication or the consumer has paid the debt, send the consumer a written notice containing\u2014\\n(1)\\nthe amount of the debt;\\n(2)\\nthe name of the creditor to whom the debt is owed;\\n(3)\\na statement that unless the consumer, within thirty days after receipt of the notice, disputes the validity of the debt, or any portion thereof, the debt will be assumed to be valid by the debt collector;\\n(4)\\na statement that if the consumer notifies the debt collector in writing within the thirty-day period that the debt, or any portion thereof, is disputed, the debt collector will obtain verification of the debt or a copy of a judgment against the consumer and a copy of such verification or judgment will be mailed to the consumer by the debt collector; and\\n(5)\\na statement that, upon the consumer\u2019s written request within the thirty-day period, the debt collector will provide the consumer with the name and address of the original creditor, if different from the current creditor.\\n(b) Disputed debts\\nIf the consumer notifies the debt collector in writing within the thirty-day period described in subsection (a) that the debt, or any portion thereof, is disputed, or that the consumer requests the name and address of the original creditor, the debt collector shall cease collection of the debt, or any disputed portion thereof, until the debt collector obtains verification of the debt or a copy of a judgment, or the name and address of the original creditor, and a copy of such verification or judgment, or name and address of the original creditor, is mailed to the consumer by the debt collector. Collection activities and communications that do not otherwise violate this subchapter may continue during the 30-day period referred to in subsection (a) unless the consumer has notified the debt collector in writing that the debt, or any portion of the debt, is disputed or that the consumer requests the name and address of the original creditor. Any collection activities and communication during the 30-day period may not overshadow or be inconsistent with the disclosure of the consumer\u2019s right to dispute the debt or request the name and address of the original creditor.\\n(c) Admission of liability\\nThe failure of a consumer to dispute the validity of a debt under this section may not be construed by any court as an admission of liability by the consumer.\\n(d) Legal pleadings\\nA communication in the form of a formal pleading in a civil action shall not be treated as an initial communication for purposes of subsection (a).\\n(e) Notice provisions\\nThe sending or delivery of any form or notice which does not relate to the collection of a debt and is expressly required by title 26, title V of Gramm-Leach-Bliley Act [ 15 U.S.C. 6801 et seq.], or any provision of Federal or State law relating to notice of data security breach or privacy, or any regulation prescribed under any such provision of law, shall not be treated as an initial communication in connection with debt collection for purposes of this section.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f809, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 879; amended Pub. L. 109\u2013351, title VIII, \u00a7\u202f802, Oct. 13, 2006, 120 Stat. 2006.)\"},\"fdcpa_1692e\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692e\",\"topic\":\"False or misleading representations\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692e\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692e - False or misleading representations\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\nA debt collector may not use any false, deceptive, or misleading representation or means in connection with the collection of any debt. Without limiting the general application of the foregoing, the following conduct is a violation of this section:\\n(1)\\nThe false representation or implication that the debt collector is vouched for, bonded by, or affiliated with the United States or any State, including the use of any badge, uniform, or facsimile thereof.\\n(2) The false representation of\u2014\\n(A)\\nthe character, amount, or legal status of any debt; or\\n(B)\\nany services rendered or compensation which may be lawfully received by any debt collector for the collection of a debt.\\n(3)\\nThe false representation or implication that any individual is an attorney or that any communication is from an attorney.\\n(4)\\nThe representation or implication that nonpayment of any debt will result in the arrest or imprisonment of any person or the seizure, garnishment, attachment, or sale of any property or wages of any person unless such action is lawful and the debt collector or creditor intends to take such action.\\n(5)\\nThe threat to take any action that cannot legally be taken or that is not intended to be taken.\\n(6) The false representation or implication that a sale, referral, or other transfer of any interest in a debt shall cause the consumer to\u2014\\n(A)\\nlose any claim or defense to payment of the debt; or\\n(B)\\nbecome subject to any practice prohibited by this subchapter.\\n(7)\\nThe false representation or implication that the consumer committed any crime or other conduct in order to disgrace the consumer.\\n(8)\\nCommunicating or threatening to communicate to any person credit information which is known or which should be known to be false, including the failure to communicate that a disputed debt is disputed.\\n(9)\\nThe use or distribution of any written communication which simulates or is falsely represented to be a document authorized, issued, or approved by any court, official, or agency of the United States or any State, or which creates a false impression as to its source, authorization, or approval.\\n(10)\\nThe use of any false representation or deceptive means to collect or attempt to collect any debt or to obtain information concerning a consumer.\\n(11)\\nThe failure to disclose in the initial written communication with the consumer and, in addition, if the initial communication with the consumer is oral, in that initial oral communication, that the debt collector is attempting to collect a debt and that any information obtained will be used for that purpose, and the failure to disclose in subsequent communications that the communication is from a debt collector, except that this paragraph shall not apply to a formal pleading made in connection with a legal action.\\n(12)\\nThe false representation or implication that accounts have been turned over to innocent purchasers for value.\\n(13)\\nThe false representation or implication that documents are legal process.\\n(14)\\nThe use of any business, company, or organization name other than the true name of the debt collector\u2019s business, company, or organization.\\n(15)\\nThe false representation or implication that documents are not legal process forms or do not require action by the consumer.\\n(16)\\nThe false representation or implication that a debt collector operates or is employed by a consumer reporting agency as defined by section 1681a(f) of this title.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f807, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 877; amended Pub. L. 104\u2013208, div. A, title II, \u00a7\u202f2305(a), Sept. 30, 1996, 110 Stat. 3009\u2013425.)\"},\"fcra_1681c-2\":{\"_meta\":{\"regulation\":\"FCRA\",\"citation\":\"15 U.S.C. \u00a71681c-2\",\"topic\":\"Identity-theft block procedure\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1681c-2 - Block of information resulting from identity theft\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Block Except as otherwise provided in this section, a consumer reporting agency shall block the reporting of any information in the file of a consumer that the consumer identifies as information that resulted from an alleged identity theft, not later than 4 business days after the date of receipt by such agency of\u2014\\n(1)\\nappropriate proof of the identity of the consumer;\\n(2)\\na copy of an identity theft report;\\n(3)\\nthe identification of such information by the consumer; and\\n(4)\\na statement by the consumer that the information is not information relating to any transaction by the consumer.\\n(b) Notification A consumer reporting agency shall promptly notify the furnisher of information identified by the consumer under subsection (a)\u2014\\n(1)\\nthat the information may be a result of identity theft;\\n(2)\\nthat an identity theft report has been filed;\\n(3)\\nthat a block has been requested under this section; and\\n(4)\\nof the effective dates of the block.\\n(c) Authority to decline or rescind\\n(1) In general A consumer reporting agency may decline to block, or may rescind any block, of information relating to a consumer under this section, if the consumer reporting agency reasonably determines that\u2014\\n(A)\\nthe information was blocked in error or a block was requested by the consumer in error;\\n(B)\\nthe information was blocked, or a block was requested by the consumer, on the basis of a material misrepresentation of fact by the consumer relevant to the request to block; or\\n(C)\\nthe consumer obtained possession of goods, services, or money as a result of the blocked transaction or transactions.\\n(2) Notification to consumer\\nIf a block of information is declined or rescinded under this subsection, the affected consumer shall be notified promptly, in the same manner as consumers are notified of the reinsertion of information under section 1681i(a)(5)(B) of this title.\\n(3) Significance of block\\nFor purposes of this subsection, if a consumer reporting agency rescinds a block, the presence of information in the file of a consumer prior to the blocking of such information is not evidence of whether the consumer knew or should have known that the consumer obtained possession of any goods, services, or money as a result of the block.\\n(d) Exception for resellers\\n(1) No reseller file This section shall not apply to a consumer reporting agency, if the consumer reporting agency \u2014\\n(A)\\nis a reseller;\\n(B)\\nis not, at the time of the request of the consumer under subsection (a), otherwise furnishing or reselling a consumer report concerning the information identified by the consumer; and\\n(C)\\ninforms the consumer, by any means, that the consumer may report the identity theft to the Bureau to obtain consumer information regarding identity theft.\\n(2) Reseller with file The sole obligation of the consumer reporting agency under this section, with regard to any request of a consumer under this section, shall be to block the consumer report maintained by the consumer reporting agency from any subsequent use, if\u2014\\n(A)\\nthe consumer, in accordance with the provisions of subsection (a), identifies, to a consumer reporting agency, information in the file of the consumer that resulted from identity theft; and\\n(B)\\nthe consumer reporting agency is a reseller of the identified information.\\n(3) Notice\\nIn carrying out its obligation under paragraph (2), the reseller shall promptly provide a notice to the consumer of the decision to block the file. Such notice shall contain the name, address, and telephone number of each consumer reporting agency from which the consumer information was obtained for resale.\\n(e) Exception for verification companies\\nThe provisions of this section do not apply to a check services company, acting as such, which issues authorizations for the purpose of approving or processing negotiable instruments, electronic fund transfers, or similar methods of payments, except that, beginning 4 business days after receipt of information described in paragraphs (1) through (3) of subsection (a), a check services company shall not report to a national consumer reporting agency described in section 1681a(p) of this title, any information identified in the subject identity theft report as resulting from identity theft.\\n(f) Access to blocked information by law enforcement agencies\\nNo provision of this section shall be construed as requiring a consumer reporting agency to prevent a Federal, State, or local law enforcement agency from accessing blocked information in a consumer file to which the agency could otherwise obtain access under this subchapter.\\n( Pub. L. 90\u2013321, title VI, \u00a7\u202f605B, as added Pub. L. 108\u2013159, title I, \u00a7\u202f152(a), Dec. 4, 2003, 117 Stat. 1964; amended Pub. L. 111\u2013203, title X, \u00a7\u202f1088(a)(2)(C), July 21, 2010, 124 Stat. 2087.)\"},\"reg_z_1026_13\":{\"_meta\":{\"regulation\":\"Regulation Z (FCBA)\",\"citation\":\"12 CFR \u00a71026.13\",\"topic\":\"Billing-error resolution procedure\",\"source_url\":\"https://www.law.cornell.edu/cfr/text/12/1026.13\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"12 CFR \u00a7 1026.13 - Billing error resolution.\\nCFR\\nTable of Popular Names\\nprev | next\\n\u00a7 1026.13 Billing error resolution.\\n(a) Definition of billing error. For purposes of this section, the term billing error means:\\n(1) A reflection on or with a periodic statement of an extension of credit that is not made to the consumer or to a person who has actual, implied, or apparent authority to use the consumer's credit card or open-end credit plan.\\n(2) A reflection on or with a periodic statement of an extension of credit that is not identified in accordance with the requirements of \u00a7\u00a7 1026.7(a)(2) or (b)(2), as applicable, and 1026.8.\\n(3) A reflection on or with a periodic statement of an extension of credit for property or services not accepted by the consumer or the consumer's designee, or not delivered to the consumer or the consumer's designee as agreed.\\n(4) A reflection on a periodic statement of the creditor's failure to credit properly a payment or other credit issued to the consumer's account.\\n(5) A reflection on a periodic statement of a computational or similar error of an accounting nature that is made by the creditor.\\n(6) A reflection on a periodic statement of an extension of credit for which the consumer requests additional clarification, including documentary evidence.\\n(7) The creditor's failure to mail or deliver a periodic statement to the consumer's last known address if that address was received by the creditor, in writing, at least 20 days before the end of the billing cycle for which the statement was required.\\n(b) Billing error notice. A billing error notice is a written notice from a consumer that:\\n(1) Is received by a creditor at the address disclosed under \u00a7 1026.7(a)(9) or (b)(9), as applicable, no later than 60 days after the creditor transmitted the first periodic statement that reflects the alleged billing error;\\n(2) Enables the creditor to identify the consumer's name and account number; and\\n(3) To the extent possible, indicates the consumer's belief and the reasons for the belief that a billing error exists, and the type, date, and amount of the error.\\n(c) Time for resolution; general procedures.\\n(1) The creditor shall mail or deliver written acknowledgment to the consumer within 30 days of receiving a billing error notice, unless the creditor has complied with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within the 30-day period; and\\n(2) The creditor shall comply with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within 2 complete billing cycles (but in no event later than 90 days) after receiving a billing error notice.\\n(d) Rules pending resolution. Until a billing error is resolved under paragraph (e) or (f) of this section, the following rules apply:\\n(1) Consumer's right to withhold disputed amount; collection action prohibited. The consumer need not pay (and the creditor may not try to collect) any portion of any required payment that the consumer believes is related to the disputed amount (including related finance or other charges). If the cardholder has enrolled in an automatic payment plan offered by the card issuer and has agreed to pay the credit card indebtedness by periodic deductions from the cardholder's deposit account, the card issuer shall not deduct any part of the disputed amount or related finance or other charges if a billing error notice is received any time up to 3 business days before the scheduled payment date.\\n(2) Adverse credit reports prohibited. The creditor or its agent shall not (directly or indirectly) make or threaten to make an adverse report to any person about the consumer's credit standing, or report that an amount or account is delinquent, because the consumer failed to pay the disputed amount or related finance or other charges.\\n(3) Acceleration of debt and restriction of account prohibited. A creditor shall not accelerate any part of the consumer's indebtedness or restrict or close a consumer's account solely because the consumer has exercised in good faith rights provided by this section. A creditor may be subject to the forfeiture penalty under 15 U.S.C. 1666(e) for failure to comply with any of the requirements of this section.\\n(4) Permitted creditor actions. A creditor is not prohibited from taking action to collect any undisputed portion of the item or bill; from deducting any disputed amount and related finance or other charges from the consumer's credit limit on the account; or from reflecting a disputed amount and related finance or other charges on a periodic statement, provided that the creditor indicates on or with the periodic statement that payment of any disputed amount and related finance or other charges is not required pending the creditor's compliance with this section.\\n(e) Procedures if billing error occurred as asserted. If a creditor determines that a billing error occurred as asserted, it shall within the time limits in paragraph (c)(2) of this section:\\n(1) Correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable; and\\n(2) Mail or deliver a correction notice to the consumer.\\n(f) Procedures if different billing error or no billing error occurred. If, after conducting a reasonable investigation, a creditor determines that no billing error occurred or that a different billing error occurred from that asserted, the creditor shall within the time limits in paragraph (c)(2) of this section:\\n(1) Mail or deliver to the consumer an explanation that sets forth the reasons for the creditor's belief that the billing error alleged by the consumer is incorrect in whole or in part;\\n(2) Furnish copies of documentary evidence of the consumer's indebtedness, if the consumer so requests; and\\n(3) If a different billing error occurred, correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable.\\n(g) Creditor's rights and duties after resolution. If a creditor, after complying with all of the requirements of this section, determines that a consumer owes all or part of the disputed amount and related finance or other charges, the creditor:\\n(1) Shall promptly notify the consumer in writing of the time when payment is due and the portion of the disputed amount and related finance or other charges that the consumer still owes;\\n(2) Shall allow any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable, during which the consumer can pay the amount due under paragraph (g)(1) of this section without incurring additional finance or other charges;\\n(3) May report an account or amount as delinquent because the amount due under paragraph (g)(1) of this section remains unpaid after the creditor has allowed any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable or 10 days (whichever is longer) during which the consumer can pay the amount; but\\n(4) May not report that an amount or account is delinquent because the amount due under paragraph (g)(1) of the section remains unpaid, if the creditor receives (within the time allowed for payment in paragraph (g)(3) of this section) further written notice from the consumer that any portion of the billing error is still in dispute, unless the creditor also:\\n(i) Promptly reports that the amount or account is in dispute;\\n(ii) Mails or delivers to the consumer (at the same time the report is made) a written notice of the name and address of each person to whom the creditor makes a report; and\\n(iii) Promptly reports any subsequent resolution of the reported delinquency to all persons to whom the creditor has made a report.\\n(h) Reassertion of billing error. A creditor that has fully complied with the requirements of this section has no further responsibilities under this section (other than as provided in paragraph (g)(4) of this section) if a consumer reasserts substantially the same billing error.\\n(i) Relation to Electronic Fund Transfer Act and Regulation E. A creditor shall comply with the requirements of Regulation E, 12 CFR 1005.11, and 1005.18(e) as applicable, governing error resolution rather than those of paragraphs (a), (b), (c), (e), (f), and (h) of this section if:\\n(1) Except with respect to a prepaid account as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs under an agreement between the consumer and a financial institution to extend credit when the consumer's account is overdrawn or to maintain a specified minimum balance in the consumer's account; or\\n(2) With regard to a covered separate credit feature and an asset feature of a prepaid account where both are accessible by a hybrid prepaid-credit card as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs when the hybrid prepaid-credit card accesses both funds in the asset feature of the prepaid account and a credit extension from the credit feature with respect to a particular transaction.\\n[ 76 FR 79772, Dec. 22, 2011, as amended at 81 FR 84369, Nov. 22, 2016]\\nElectronic Fund Transfer Act\\nCFR Toolbox\\nLaw about... Articles from Wex\\nTable of Popular Names\\nParallel Table of Authorities\\nAccessibility\\nAbout LII\\nContact us\\nAdvertise here\\nHelp\\nTerms of use\\nPrivacy\"},\"cfpb_15day_rule\":{\"_meta\":{\"regulation\":\"CFPB complaint rule\",\"citation\":\"Dodd-Frank Act company-response standard\",\"topic\":\"Company response deadline\",\"source_url\":\"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\"sourcing_note\":\"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"},\"text\":\"The Dodd-Frank Wall Street Reform and Consumer Protection Act requires the CFPB to collect, investigate, and respond to consumer complaints about financial products and services. Once the CFPB sends a complaint to a company, the company reviews the information, communicates with the consumer as needed, and determines what action to take in response.\\n\\nCompany responds: your company provides a response within 15 calendar days.\\n\\nIf your response is not final, let us know. Your company will then have up to 60 calendar days to provide a final response.\\n\\nComplaints are typically published on the Consumer Complaint Database after the company responds, or after 15 days, whichever comes first, and the consumer is given the opportunity to review the company's response.\"}};\nconst CITATION_TO_FILE = {\"1692g\":\"fdcpa_1692g\",\"1692e\":\"fdcpa_1692e\",\"1681c-2\":\"fcra_1681c-2\",\"1026.13\":\"reg_z_1026_13\"};\n\nfunction fetchExactClause(regulations, citationToFile, citation) {\r\n  const sectionMatch = citation.match(/(1692[a-z]|1681c-2|1026\\.13)/);\r\n  const subsectionMatch = citation.match(/\\(([a-z])\\)/);\r\n  if (!sectionMatch) return { found: false, note: `Could not parse section from citation '${citation}'.` };\r\n\r\n  const fileKey = citationToFile[sectionMatch[1]];\r\n  const doc = regulations[fileKey];\r\n  if (!doc) return { found: false, note: `No cached regulation file for section '${sectionMatch[1]}'.` };\r\n\r\n  if (!subsectionMatch) {\r\n    return { found: true, citation, full_text: doc.text, note: \"No specific subsection in citation; returning full section text.\" };\r\n  }\r\n\r\n  const letter = subsectionMatch[1];\r\n  const text = doc.text;\r\n  const startMarker = `\\n(${letter})`;\r\n  const startIdx = text.indexOf(startMarker);\r\n  if (startIdx === -1) return { found: false, note: `Subsection (${letter}) not found in ${fileKey}.` };\r\n\r\n  const nextLetterCode = letter.charCodeAt(0) + 1;\r\n  const nextMarker = `\\n(${String.fromCharCode(nextLetterCode)})`;\r\n  let endIdx = text.indexOf(nextMarker, startIdx + 1);\r\n  if (endIdx === -1) endIdx = text.length;\r\n\r\n  return { found: true, citation, subsection: letter, clause_text: text.slice(startIdx, endIdx).trim(), source_citation: doc._meta.citation };\r\n}\n\nconst ticket = $input.item.json;\nconst result = fetchExactClause(REGULATIONS, CITATION_TO_FILE, ticket._agent3_cited_clause);\nreturn { json: { ...ticket, agent3_tool_result: result } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000010",
      "name": "Tool: Exact Regulation Clause Fetch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3380,
        -260
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001e",
      "name": "Merge: Pre-Agent 4",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        3480,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Agent 4: QA / escalation-scoring -- MOCKED reasoning layer. Returns the\n// literal Section 6 fixture confidence/requires_human/reason. reverify_clause\n// and reverify_crm_field tell the next node what to re-check (the real work).\nconst AGENT4_FIXTURES = {\n  \"9999970\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"confidence\": 0.55,\n      \"requires_human\": true,\n      \"reason\": \"Servicemember + attorney/FTC mention + disputed dates in collector's own response\"\n    },\n    \"reverify_clause\": \"15 U.S.C. \u00a71692g(b)\",\n    \"reverify_crm_field\": \"tenure_years\"\n  },\n  \"9999975\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"confidence\": 0.4,\n      \"requires_human\": true,\n      \"reason\": \"Identity-theft indicator \u2014 flagged high-risk regardless of draft quality\"\n    },\n    \"reverify_clause\": \"15 U.S.C. \u00a71681c-2\",\n    \"reverify_crm_field\": \"prior_complaints_12mo\"\n  },\n  \"9999983\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"confidence\": 0.5,\n      \"requires_human\": true,\n      \"reason\": \"Primary issue is identity-theft-adjacent \u2014 high-risk category requires human review regardless of how straightforward the secondary service issue is\"\n    },\n    \"reverify_clause\": \"15 U.S.C. \u00a71681c-2\",\n    \"reverify_crm_field\": \"prior_complaints_12mo\"\n  },\n  \"24157195\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.88,\n      \"requires_human\": false,\n      \"reason\": \"Generic, high-volume dispute category ('Debt is not yours', not flagged high-risk); no narrative to conflict with, zero prior complaints, no special-population flag, no other CRM or narrative risk signal -- a standard acknowledgment response is appropriate without human review\"\n    }\n  },\n  \"24157200\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.48,\n      \"requires_human\": true,\n      \"reason\": \"Consumer's claim cites a specific FCRA disclosure requirement this build's regulation corpus doesn't cover, and CRM shows 2 prior complaints in 12 months -- both independently warrant human review\"\n    }\n  },\n  \"24157240\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.85,\n      \"requires_human\": false,\n      \"reason\": \"Generic, high-volume dispute category ('Debt is not yours', not flagged high-risk); broader CRM context shows no pattern of repeat disputes or account friction, zero prior complaints, no special-population flag -- a standard acknowledgment response is appropriate without human review\"\n    }\n  },\n  \"24157473\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.5,\n      \"requires_human\": true,\n      \"reason\": \"Claim rests on a state statute outside the cached regulation corpus -- nothing to verify against this build's reference data, and state-law compliance questions warrant human review regardless\"\n    }\n  },\n  \"24157609\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.42,\n      \"requires_human\": true,\n      \"reason\": \"CFPB's own filed sub-issue is 'Debt was result of identity theft' -- a serious, real government classification -- but there is no consumer narrative to substantiate it and Agent 2's regulation-search tool found no supporting citation; flagging for human review because the filed category and the available evidence are mismatched, not because either signal alone is routine\"\n    }\n  },\n  \"24157871\": {\n    \"tool_used\": false,\n    \"output\": {\n      \"confidence\": 0.45,\n      \"requires_human\": true,\n      \"reason\": \"No regulation match to verify; an excessive-contact pattern (9 calls/8 voicemails in 7 minutes) plus a disputed 'already paid' claim leaves high uncertainty without a citable rule to anchor the QA check\"\n    }\n  },\n  \"24158082\": {\n    \"tool_used\": true,\n    \"output\": {\n      \"confidence\": 0.58,\n      \"requires_human\": true,\n      \"reason\": \"Consumer holds documentary evidence ($0-balance receipt) directly contradicting the claimed $550 balance, and CRM shows 3 prior complaints in 12 months -- a real evidentiary conflict plus a repeat-complainant pattern\"\n    },\n    \"reverify_clause\": \"15 U.S.C. \u00a71692g(b)\",\n    \"reverify_crm_field\": \"prior_complaints_12mo\"\n  }\n};\n\nconst ticket = $input.item.json;\nconst fixture = AGENT4_FIXTURES[String(ticket.complaint_id)];\nif (!fixture) {\n  return { json: { ...ticket, _mock_unavailable: true, agent4_tool_used: false, agent4_output: null } };\n}\nreturn {\n  json: {\n    ...ticket, agent4_tool_used: fixture.tool_used, agent4_output: fixture.output,\n    _agent4_reverify_clause: fixture.reverify_clause, _agent4_reverify_crm_field: fixture.reverify_crm_field,\n  },\n};"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000011",
      "name": "Agent 4: Mock QA Decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3600,
        -140
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-000000000012-cond",
              "leftValue": "={{ $json.agent4_tool_used }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000012",
      "name": "IF: Agent 4 Tool Used?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3820,
        -140
      ],
      "notesInFlow": true,
      "notes": "Only when the draft makes a checkable claim (spec Section 6). Untested false branch: all three fixtures make one."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Tool 4 (real): re-verify a cited clause (re-runs the same exact-clause-fetch\n// logic Agent 3 uses, confirming the citation genuinely resolves) and\n// re-check a CRM fact directly off the record, not off Agent 2's paraphrase\n// of it -- catches the case where a draft misquotes what the CRM actually says.\nconst REGULATIONS = {\"fdcpa_1692g\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692g\",\"topic\":\"Debt validation notice\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692g\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket A (Aargon Agency) -- 30-day validation dispute.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692g - Validation of debts\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Notice of debt; contents Within five days after the initial communication with a consumer in connection with the collection of any debt, a debt collector shall, unless the following information is contained in the initial communication or the consumer has paid the debt, send the consumer a written notice containing\u2014\\n(1)\\nthe amount of the debt;\\n(2)\\nthe name of the creditor to whom the debt is owed;\\n(3)\\na statement that unless the consumer, within thirty days after receipt of the notice, disputes the validity of the debt, or any portion thereof, the debt will be assumed to be valid by the debt collector;\\n(4)\\na statement that if the consumer notifies the debt collector in writing within the thirty-day period that the debt, or any portion thereof, is disputed, the debt collector will obtain verification of the debt or a copy of a judgment against the consumer and a copy of such verification or judgment will be mailed to the consumer by the debt collector; and\\n(5)\\na statement that, upon the consumer\u2019s written request within the thirty-day period, the debt collector will provide the consumer with the name and address of the original creditor, if different from the current creditor.\\n(b) Disputed debts\\nIf the consumer notifies the debt collector in writing within the thirty-day period described in subsection (a) that the debt, or any portion thereof, is disputed, or that the consumer requests the name and address of the original creditor, the debt collector shall cease collection of the debt, or any disputed portion thereof, until the debt collector obtains verification of the debt or a copy of a judgment, or the name and address of the original creditor, and a copy of such verification or judgment, or name and address of the original creditor, is mailed to the consumer by the debt collector. Collection activities and communications that do not otherwise violate this subchapter may continue during the 30-day period referred to in subsection (a) unless the consumer has notified the debt collector in writing that the debt, or any portion of the debt, is disputed or that the consumer requests the name and address of the original creditor. Any collection activities and communication during the 30-day period may not overshadow or be inconsistent with the disclosure of the consumer\u2019s right to dispute the debt or request the name and address of the original creditor.\\n(c) Admission of liability\\nThe failure of a consumer to dispute the validity of a debt under this section may not be construed by any court as an admission of liability by the consumer.\\n(d) Legal pleadings\\nA communication in the form of a formal pleading in a civil action shall not be treated as an initial communication for purposes of subsection (a).\\n(e) Notice provisions\\nThe sending or delivery of any form or notice which does not relate to the collection of a debt and is expressly required by title 26, title V of Gramm-Leach-Bliley Act [ 15 U.S.C. 6801 et seq.], or any provision of Federal or State law relating to notice of data security breach or privacy, or any regulation prescribed under any such provision of law, shall not be treated as an initial communication in connection with debt collection for purposes of this section.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f809, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 879; amended Pub. L. 109\u2013351, title VIII, \u00a7\u202f802, Oct. 13, 2006, 120 Stat. 2006.)\"},\"fdcpa_1692e\":{\"_meta\":{\"regulation\":\"FDCPA\",\"citation\":\"15 U.S.C. \u00a71692e\",\"topic\":\"False or misleading representations\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1692e\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) -- alongside FCRA \u00a7605B for a debt-not-owed / identity-theft-profile claim.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1692e - False or misleading representations\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\nA debt collector may not use any false, deceptive, or misleading representation or means in connection with the collection of any debt. Without limiting the general application of the foregoing, the following conduct is a violation of this section:\\n(1)\\nThe false representation or implication that the debt collector is vouched for, bonded by, or affiliated with the United States or any State, including the use of any badge, uniform, or facsimile thereof.\\n(2) The false representation of\u2014\\n(A)\\nthe character, amount, or legal status of any debt; or\\n(B)\\nany services rendered or compensation which may be lawfully received by any debt collector for the collection of a debt.\\n(3)\\nThe false representation or implication that any individual is an attorney or that any communication is from an attorney.\\n(4)\\nThe representation or implication that nonpayment of any debt will result in the arrest or imprisonment of any person or the seizure, garnishment, attachment, or sale of any property or wages of any person unless such action is lawful and the debt collector or creditor intends to take such action.\\n(5)\\nThe threat to take any action that cannot legally be taken or that is not intended to be taken.\\n(6) The false representation or implication that a sale, referral, or other transfer of any interest in a debt shall cause the consumer to\u2014\\n(A)\\nlose any claim or defense to payment of the debt; or\\n(B)\\nbecome subject to any practice prohibited by this subchapter.\\n(7)\\nThe false representation or implication that the consumer committed any crime or other conduct in order to disgrace the consumer.\\n(8)\\nCommunicating or threatening to communicate to any person credit information which is known or which should be known to be false, including the failure to communicate that a disputed debt is disputed.\\n(9)\\nThe use or distribution of any written communication which simulates or is falsely represented to be a document authorized, issued, or approved by any court, official, or agency of the United States or any State, or which creates a false impression as to its source, authorization, or approval.\\n(10)\\nThe use of any false representation or deceptive means to collect or attempt to collect any debt or to obtain information concerning a consumer.\\n(11)\\nThe failure to disclose in the initial written communication with the consumer and, in addition, if the initial communication with the consumer is oral, in that initial oral communication, that the debt collector is attempting to collect a debt and that any information obtained will be used for that purpose, and the failure to disclose in subsequent communications that the communication is from a debt collector, except that this paragraph shall not apply to a formal pleading made in connection with a legal action.\\n(12)\\nThe false representation or implication that accounts have been turned over to innocent purchasers for value.\\n(13)\\nThe false representation or implication that documents are legal process.\\n(14)\\nThe use of any business, company, or organization name other than the true name of the debt collector\u2019s business, company, or organization.\\n(15)\\nThe false representation or implication that documents are not legal process forms or do not require action by the consumer.\\n(16)\\nThe false representation or implication that a debt collector operates or is employed by a consumer reporting agency as defined by section 1681a(f) of this title.\\n( Pub. L. 90\u2013321, title VIII, \u00a7\u202f807, as added Pub. L. 95\u2013109, Sept. 20, 1977, 91 Stat. 877; amended Pub. L. 104\u2013208, div. A, title II, \u00a7\u202f2305(a), Sept. 30, 1996, 110 Stat. 3009\u2013425.)\"},\"fcra_1681c-2\":{\"_meta\":{\"regulation\":\"FCRA\",\"citation\":\"15 U.S.C. \u00a71681c-2\",\"topic\":\"Identity-theft block procedure\",\"source_url\":\"https://www.law.cornell.edu/uscode/text/15/1681c-2\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Ticket B (Equifax) and Ticket C (Chase) -- identity-theft / unauthorized-account block requests.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"15 U.S. Code \u00a7 1681c-2 - Block of information resulting from identity theft\\nU.S. Code\\nNotes\\nAuthorities (CFR)\\nprev | next\\n(a) Block Except as otherwise provided in this section, a consumer reporting agency shall block the reporting of any information in the file of a consumer that the consumer identifies as information that resulted from an alleged identity theft, not later than 4 business days after the date of receipt by such agency of\u2014\\n(1)\\nappropriate proof of the identity of the consumer;\\n(2)\\na copy of an identity theft report;\\n(3)\\nthe identification of such information by the consumer; and\\n(4)\\na statement by the consumer that the information is not information relating to any transaction by the consumer.\\n(b) Notification A consumer reporting agency shall promptly notify the furnisher of information identified by the consumer under subsection (a)\u2014\\n(1)\\nthat the information may be a result of identity theft;\\n(2)\\nthat an identity theft report has been filed;\\n(3)\\nthat a block has been requested under this section; and\\n(4)\\nof the effective dates of the block.\\n(c) Authority to decline or rescind\\n(1) In general A consumer reporting agency may decline to block, or may rescind any block, of information relating to a consumer under this section, if the consumer reporting agency reasonably determines that\u2014\\n(A)\\nthe information was blocked in error or a block was requested by the consumer in error;\\n(B)\\nthe information was blocked, or a block was requested by the consumer, on the basis of a material misrepresentation of fact by the consumer relevant to the request to block; or\\n(C)\\nthe consumer obtained possession of goods, services, or money as a result of the blocked transaction or transactions.\\n(2) Notification to consumer\\nIf a block of information is declined or rescinded under this subsection, the affected consumer shall be notified promptly, in the same manner as consumers are notified of the reinsertion of information under section 1681i(a)(5)(B) of this title.\\n(3) Significance of block\\nFor purposes of this subsection, if a consumer reporting agency rescinds a block, the presence of information in the file of a consumer prior to the blocking of such information is not evidence of whether the consumer knew or should have known that the consumer obtained possession of any goods, services, or money as a result of the block.\\n(d) Exception for resellers\\n(1) No reseller file This section shall not apply to a consumer reporting agency, if the consumer reporting agency \u2014\\n(A)\\nis a reseller;\\n(B)\\nis not, at the time of the request of the consumer under subsection (a), otherwise furnishing or reselling a consumer report concerning the information identified by the consumer; and\\n(C)\\ninforms the consumer, by any means, that the consumer may report the identity theft to the Bureau to obtain consumer information regarding identity theft.\\n(2) Reseller with file The sole obligation of the consumer reporting agency under this section, with regard to any request of a consumer under this section, shall be to block the consumer report maintained by the consumer reporting agency from any subsequent use, if\u2014\\n(A)\\nthe consumer, in accordance with the provisions of subsection (a), identifies, to a consumer reporting agency, information in the file of the consumer that resulted from identity theft; and\\n(B)\\nthe consumer reporting agency is a reseller of the identified information.\\n(3) Notice\\nIn carrying out its obligation under paragraph (2), the reseller shall promptly provide a notice to the consumer of the decision to block the file. Such notice shall contain the name, address, and telephone number of each consumer reporting agency from which the consumer information was obtained for resale.\\n(e) Exception for verification companies\\nThe provisions of this section do not apply to a check services company, acting as such, which issues authorizations for the purpose of approving or processing negotiable instruments, electronic fund transfers, or similar methods of payments, except that, beginning 4 business days after receipt of information described in paragraphs (1) through (3) of subsection (a), a check services company shall not report to a national consumer reporting agency described in section 1681a(p) of this title, any information identified in the subject identity theft report as resulting from identity theft.\\n(f) Access to blocked information by law enforcement agencies\\nNo provision of this section shall be construed as requiring a consumer reporting agency to prevent a Federal, State, or local law enforcement agency from accessing blocked information in a consumer file to which the agency could otherwise obtain access under this subchapter.\\n( Pub. L. 90\u2013321, title VI, \u00a7\u202f605B, as added Pub. L. 108\u2013159, title I, \u00a7\u202f152(a), Dec. 4, 2003, 117 Stat. 1964; amended Pub. L. 111\u2013203, title X, \u00a7\u202f1088(a)(2)(C), July 21, 2010, 124 Stat. 2087.)\"},\"reg_z_1026_13\":{\"_meta\":{\"regulation\":\"Regulation Z (FCBA)\",\"citation\":\"12 CFR \u00a71026.13\",\"topic\":\"Billing-error resolution procedure\",\"source_url\":\"https://www.law.cornell.edu/cfr/text/12/1026.13\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Credit-card billing disputes (pilot scope, Section 4) -- not cited in the three worked Section 6 tickets.\",\"sourcing_note\":\"Verbatim public-domain statutory/regulatory text as published by Cornell Legal Information Institute (law.cornell.edu). Cached once at build time per spec Section 3b -- stable statutory text, not re-fetched per ticket. Not legal advice; this is a technical demonstration (spec Section 14, disclosure 4).\"},\"text\":\"12 CFR \u00a7 1026.13 - Billing error resolution.\\nCFR\\nTable of Popular Names\\nprev | next\\n\u00a7 1026.13 Billing error resolution.\\n(a) Definition of billing error. For purposes of this section, the term billing error means:\\n(1) A reflection on or with a periodic statement of an extension of credit that is not made to the consumer or to a person who has actual, implied, or apparent authority to use the consumer's credit card or open-end credit plan.\\n(2) A reflection on or with a periodic statement of an extension of credit that is not identified in accordance with the requirements of \u00a7\u00a7 1026.7(a)(2) or (b)(2), as applicable, and 1026.8.\\n(3) A reflection on or with a periodic statement of an extension of credit for property or services not accepted by the consumer or the consumer's designee, or not delivered to the consumer or the consumer's designee as agreed.\\n(4) A reflection on a periodic statement of the creditor's failure to credit properly a payment or other credit issued to the consumer's account.\\n(5) A reflection on a periodic statement of a computational or similar error of an accounting nature that is made by the creditor.\\n(6) A reflection on a periodic statement of an extension of credit for which the consumer requests additional clarification, including documentary evidence.\\n(7) The creditor's failure to mail or deliver a periodic statement to the consumer's last known address if that address was received by the creditor, in writing, at least 20 days before the end of the billing cycle for which the statement was required.\\n(b) Billing error notice. A billing error notice is a written notice from a consumer that:\\n(1) Is received by a creditor at the address disclosed under \u00a7 1026.7(a)(9) or (b)(9), as applicable, no later than 60 days after the creditor transmitted the first periodic statement that reflects the alleged billing error;\\n(2) Enables the creditor to identify the consumer's name and account number; and\\n(3) To the extent possible, indicates the consumer's belief and the reasons for the belief that a billing error exists, and the type, date, and amount of the error.\\n(c) Time for resolution; general procedures.\\n(1) The creditor shall mail or deliver written acknowledgment to the consumer within 30 days of receiving a billing error notice, unless the creditor has complied with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within the 30-day period; and\\n(2) The creditor shall comply with the appropriate resolution procedures of paragraphs (e) and (f) of this section, as applicable, within 2 complete billing cycles (but in no event later than 90 days) after receiving a billing error notice.\\n(d) Rules pending resolution. Until a billing error is resolved under paragraph (e) or (f) of this section, the following rules apply:\\n(1) Consumer's right to withhold disputed amount; collection action prohibited. The consumer need not pay (and the creditor may not try to collect) any portion of any required payment that the consumer believes is related to the disputed amount (including related finance or other charges). If the cardholder has enrolled in an automatic payment plan offered by the card issuer and has agreed to pay the credit card indebtedness by periodic deductions from the cardholder's deposit account, the card issuer shall not deduct any part of the disputed amount or related finance or other charges if a billing error notice is received any time up to 3 business days before the scheduled payment date.\\n(2) Adverse credit reports prohibited. The creditor or its agent shall not (directly or indirectly) make or threaten to make an adverse report to any person about the consumer's credit standing, or report that an amount or account is delinquent, because the consumer failed to pay the disputed amount or related finance or other charges.\\n(3) Acceleration of debt and restriction of account prohibited. A creditor shall not accelerate any part of the consumer's indebtedness or restrict or close a consumer's account solely because the consumer has exercised in good faith rights provided by this section. A creditor may be subject to the forfeiture penalty under 15 U.S.C. 1666(e) for failure to comply with any of the requirements of this section.\\n(4) Permitted creditor actions. A creditor is not prohibited from taking action to collect any undisputed portion of the item or bill; from deducting any disputed amount and related finance or other charges from the consumer's credit limit on the account; or from reflecting a disputed amount and related finance or other charges on a periodic statement, provided that the creditor indicates on or with the periodic statement that payment of any disputed amount and related finance or other charges is not required pending the creditor's compliance with this section.\\n(e) Procedures if billing error occurred as asserted. If a creditor determines that a billing error occurred as asserted, it shall within the time limits in paragraph (c)(2) of this section:\\n(1) Correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable; and\\n(2) Mail or deliver a correction notice to the consumer.\\n(f) Procedures if different billing error or no billing error occurred. If, after conducting a reasonable investigation, a creditor determines that no billing error occurred or that a different billing error occurred from that asserted, the creditor shall within the time limits in paragraph (c)(2) of this section:\\n(1) Mail or deliver to the consumer an explanation that sets forth the reasons for the creditor's belief that the billing error alleged by the consumer is incorrect in whole or in part;\\n(2) Furnish copies of documentary evidence of the consumer's indebtedness, if the consumer so requests; and\\n(3) If a different billing error occurred, correct the billing error and credit the consumer's account with any disputed amount and related finance or other charges, as applicable.\\n(g) Creditor's rights and duties after resolution. If a creditor, after complying with all of the requirements of this section, determines that a consumer owes all or part of the disputed amount and related finance or other charges, the creditor:\\n(1) Shall promptly notify the consumer in writing of the time when payment is due and the portion of the disputed amount and related finance or other charges that the consumer still owes;\\n(2) Shall allow any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable, during which the consumer can pay the amount due under paragraph (g)(1) of this section without incurring additional finance or other charges;\\n(3) May report an account or amount as delinquent because the amount due under paragraph (g)(1) of this section remains unpaid after the creditor has allowed any time period disclosed under \u00a7 1026.6(a)(1) or (b)(2)(v), as applicable, and \u00a7 1026.7(a)(8) or (b)(8), as applicable or 10 days (whichever is longer) during which the consumer can pay the amount; but\\n(4) May not report that an amount or account is delinquent because the amount due under paragraph (g)(1) of the section remains unpaid, if the creditor receives (within the time allowed for payment in paragraph (g)(3) of this section) further written notice from the consumer that any portion of the billing error is still in dispute, unless the creditor also:\\n(i) Promptly reports that the amount or account is in dispute;\\n(ii) Mails or delivers to the consumer (at the same time the report is made) a written notice of the name and address of each person to whom the creditor makes a report; and\\n(iii) Promptly reports any subsequent resolution of the reported delinquency to all persons to whom the creditor has made a report.\\n(h) Reassertion of billing error. A creditor that has fully complied with the requirements of this section has no further responsibilities under this section (other than as provided in paragraph (g)(4) of this section) if a consumer reasserts substantially the same billing error.\\n(i) Relation to Electronic Fund Transfer Act and Regulation E. A creditor shall comply with the requirements of Regulation E, 12 CFR 1005.11, and 1005.18(e) as applicable, governing error resolution rather than those of paragraphs (a), (b), (c), (e), (f), and (h) of this section if:\\n(1) Except with respect to a prepaid account as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs under an agreement between the consumer and a financial institution to extend credit when the consumer's account is overdrawn or to maintain a specified minimum balance in the consumer's account; or\\n(2) With regard to a covered separate credit feature and an asset feature of a prepaid account where both are accessible by a hybrid prepaid-credit card as defined in \u00a7 1026.61, an extension of credit that is incident to an electronic fund transfer occurs when the hybrid prepaid-credit card accesses both funds in the asset feature of the prepaid account and a credit extension from the credit feature with respect to a particular transaction.\\n[ 76 FR 79772, Dec. 22, 2011, as amended at 81 FR 84369, Nov. 22, 2016]\\nElectronic Fund Transfer Act\\nCFR Toolbox\\nLaw about... Articles from Wex\\nTable of Popular Names\\nParallel Table of Authorities\\nAccessibility\\nAbout LII\\nContact us\\nAdvertise here\\nHelp\\nTerms of use\\nPrivacy\"},\"cfpb_15day_rule\":{\"_meta\":{\"regulation\":\"CFPB complaint rule\",\"citation\":\"Dodd-Frank Act company-response standard\",\"topic\":\"Company response deadline\",\"source_url\":\"https://www.consumerfinance.gov/compliance/consumer-complaint-program/company-process/\",\"retrieved_date\":\"2026-08-12\",\"pilot_relevance\":\"Applies to every complaint in the pilot -- backs the SLA compliance metric (spec Section 9).\",\"sourcing_note\":\"CFPB's own published complaint-handling standard, quoted from its official process page. Cached once at build time per spec Section 3b.\"},\"text\":\"The Dodd-Frank Wall Street Reform and Consumer Protection Act requires the CFPB to collect, investigate, and respond to consumer complaints about financial products and services. Once the CFPB sends a complaint to a company, the company reviews the information, communicates with the consumer as needed, and determines what action to take in response.\\n\\nCompany responds: your company provides a response within 15 calendar days.\\n\\nIf your response is not final, let us know. Your company will then have up to 60 calendar days to provide a final response.\\n\\nComplaints are typically published on the Consumer Complaint Database after the company responds, or after 15 days, whichever comes first, and the consumer is given the opportunity to review the company's response.\"}};\nconst CITATION_TO_FILE = {\"1692g\":\"fdcpa_1692g\",\"1692e\":\"fdcpa_1692e\",\"1681c-2\":\"fcra_1681c-2\",\"1026.13\":\"reg_z_1026_13\"};\n\nfunction fetchExactClause(regulations, citationToFile, citation) {\r\n  const sectionMatch = citation.match(/(1692[a-z]|1681c-2|1026\\.13)/);\r\n  const subsectionMatch = citation.match(/\\(([a-z])\\)/);\r\n  if (!sectionMatch) return { found: false, note: `Could not parse section from citation '${citation}'.` };\r\n\r\n  const fileKey = citationToFile[sectionMatch[1]];\r\n  const doc = regulations[fileKey];\r\n  if (!doc) return { found: false, note: `No cached regulation file for section '${sectionMatch[1]}'.` };\r\n\r\n  if (!subsectionMatch) {\r\n    return { found: true, citation, full_text: doc.text, note: \"No specific subsection in citation; returning full section text.\" };\r\n  }\r\n\r\n  const letter = subsectionMatch[1];\r\n  const text = doc.text;\r\n  const startMarker = `\\n(${letter})`;\r\n  const startIdx = text.indexOf(startMarker);\r\n  if (startIdx === -1) return { found: false, note: `Subsection (${letter}) not found in ${fileKey}.` };\r\n\r\n  const nextLetterCode = letter.charCodeAt(0) + 1;\r\n  const nextMarker = `\\n(${String.fromCharCode(nextLetterCode)})`;\r\n  let endIdx = text.indexOf(nextMarker, startIdx + 1);\r\n  if (endIdx === -1) endIdx = text.length;\r\n\r\n  return { found: true, citation, subsection: letter, clause_text: text.slice(startIdx, endIdx).trim(), source_citation: doc._meta.citation };\r\n}\n\nconst ticket = $input.item.json;\nconst clause_reverified = fetchExactClause(REGULATIONS, CITATION_TO_FILE, ticket._agent4_reverify_clause);\nconst field = ticket._agent4_reverify_crm_field;\nconst crm_fact_reverified = { field, value: ticket.crm[field] };\nreturn { json: { ...ticket, agent4_tool_result: { clause_reverified, crm_fact_reverified } } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000013",
      "name": "Tool: Re-verify Clause & CRM Fact",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4040,
        -260
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001f",
      "name": "Merge: Pre-Escalation Signals",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        4140,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Deterministic escalation-signal computation (spec Section 7, resolved v7).\n// This is NOT a fifth agent call -- it's a plain rules evaluation over the\n// four agents' already-produced structured outputs plus the CRM record,\n// feeding a single boolean into the IF node that follows.\n//   1. Monetary exposure is read from the NARRATIVE only (best-effort dollar\n//      extraction), never crm.outstanding_balance_usd -- balance already has\n//      its own independent trigger via isHighValueAccount, so reusing it\n//      here would double-count the same number under two different labels.\n//   2. High-risk issue type is matched against Agent 1's classified\n//      issue/sub_issue value against an explicit list drawn from the real\n//      cached taxonomy, and/or a citation-based marker (FCRA \u00a71681c-2) --\n//      never the raw narrative text, which would repeat Ticket C's original\n//      failure mode of pattern-matching on surface wording instead of\n//      trusting the structured classification.\nconst HIGH_RISK_ISSUES = new Set([\"Took or threatened to take negative or legal action\",\"Threatened or suggested your credit would be damaged\",\"Threatened to sue you for very old debt\",\"Threatened to arrest you or take you to jail if you do not pay\",\"Threatened to turn you in to immigration or deport you\",\"Used obscene, profane, or other abusive language\",\"Used obscene/profane/abusive language\",\"Threatened to contact someone or share information improperly\",\"Taking/threatening an illegal action\",\"Threatened to sue on too old debt\",\"Threatened arrest/jail if do not pay\",\"Debt was result of identity theft\",\"Debt resulted from identity theft\",\"Identity theft / Fraud / Embezzlement\",\"Problem with fraud alerts or security freezes\",\"Credit monitoring or identity theft protection services\"]);\nconst HIGH_RISK_CITATION_MARKERS = [\"1681c-2\"];\n\nfunction extractNarrativeMonetaryExposure(narrativeText) {\r\n  if (!narrativeText) return null;\r\n  const matches = narrativeText.match(/\\$\\s?[\\d,]+(?:\\.\\d{1,2})?/g);\r\n  if (!matches) return null;\r\n  const amounts = matches.map((m) => parseFloat(m.replace(/[$,\\s]/g, \"\")));\r\n  return Math.max(...amounts);\r\n}\n\nfunction computeEscalationSignals(ticket, agent1Output, agent2Output, agent4Output, highRiskIssues, highRiskCitationMarkers) {\r\n  const requiresHuman = agent4Output.requires_human === true;\r\n  const lowConfidence = agent4Output.confidence < 0.7;\r\n\r\n  const classifiedIssues = agent1Output.issues ? agent1Output.issues.map((i) => i.issue) : [agent1Output.issue];\r\n  const matchesHighRiskIssue = classifiedIssues.some((issue) => highRiskIssues.has(issue));\r\n  const regulationText = `${agent2Output.applicable_regulation || \"\"} ${agent2Output.citation || \"\"}`;\r\n  const matchesHighRiskCitation = highRiskCitationMarkers.some((marker) => regulationText.includes(marker));\r\n  const isHighRiskIssue = matchesHighRiskIssue || matchesHighRiskCitation;\r\n\r\n  const isRepeatComplainant = ticket.crm.prior_complaints_12mo >= 2;\r\n  const isHighValueAccount =\r\n    ticket.crm.account_tier === \"Premier\" ||\r\n    (ticket.crm.tenure_years >= 5 && ticket.crm.product_holdings.length >= 2) ||\r\n    ticket.crm.outstanding_balance_usd >= 10000;\r\n\r\n  // Narrative-extracted only -- CRM balance deliberately excluded (spec v7):\r\n  // outstanding_balance_usd already has its own independent trigger via\r\n  // isHighValueAccount, so reusing it here would double-count the same\r\n  // number under two different labels.\r\n  const statedMonetaryExposure = extractNarrativeMonetaryExposure(ticket.complaint_what_happened);\r\n  const exceedsMonetaryThreshold = statedMonetaryExposure !== null && statedMonetaryExposure > 500;\r\n\r\n  const escalate = requiresHuman || lowConfidence || isHighRiskIssue || isRepeatComplainant || isHighValueAccount || exceedsMonetaryThreshold;\r\n\r\n  return { requiresHuman, lowConfidence, isHighRiskIssue, isRepeatComplainant, isHighValueAccount, exceedsMonetaryThreshold, statedMonetaryExposure, escalate };\r\n}\n\nconst ticket = $input.item.json;\nconst signals = computeEscalationSignals(ticket, ticket.agent1_output, ticket.agent2_output, ticket.agent4_output, HIGH_RISK_ISSUES, HIGH_RISK_CITATION_MARKERS);\nreturn { json: { ...ticket, escalation_signals: signals, escalate: signals.escalate } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000014",
      "name": "Compute Escalation Signals",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4260,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Ground-truth comparison (spec Section 8 / Section 15 Phase 5). Section 8\n// names three CFPB outcome fields: company response category, timely flag,\n// disputed flag. The live API does not expose a disputed flag at all --\n// confirmed by inspecting real records during this build (CFPB discontinued\n// it from the public schema years ago), not assumed from the spec text.\n// This uses only the two fields that actually exist; the third is reported\n// as explicitly unavailable rather than silently dropped.\n//\n// \"Elevated\" vs. \"routine\" is a deliberately coarse, directional proxy --\n// reported as \"X% agreement,\" never as accuracy (spec Section 8's own\n// framing). Note from testing against the three fixtures: all three read as\n// \"routine\" (Closed with explanation + timely) yet the pipeline correctly\n// escalates all three on narrative/regulatory grounds -- that's not a bug,\n// it's exactly why this must never be read as an accuracy score. CFPB's own\n// outcome categories are coarser than the severity rubric.\nfunction computeGroundTruthAgreement(ticket, escalate) {\r\n  const isTimely = ticket.timely === \"Yes\";\r\n  // Negative lookbehind, not a plain /monetary relief/i test: CFPB's real\r\n  // company_response schema has a DISTINCT \"Closed with non-monetary relief\"\r\n  // category, which contains the substring \"monetary relief\" and would\r\n  // otherwise be misread as the company having paid the consumer something.\r\n  // Found via a real ticket (24157609, CL Holdings LLC) the first time this\r\n  // build processed a live batch that happened to include that response\r\n  // value -- the three original Section 6 fixtures all share \"Closed with\r\n  // explanation\" and never exercised this branch.\r\n  const gotMonetaryRelief = /(?<!non-)monetary relief/i.test(ticket.company_response || \"\");\r\n  const groundTruthSignal = (!isTimely || gotMonetaryRelief) ? \"elevated\" : \"routine\";\r\n  const agreesWithGroundTruth = (escalate && groundTruthSignal === \"elevated\") || (!escalate && groundTruthSignal === \"routine\");\r\n\r\n  return {\r\n    cfpb_company_response: ticket.company_response,\r\n    cfpb_timely: ticket.timely,\r\n    cfpb_disputed_flag: \"unavailable \u2014 CFPB discontinued this field from the public API\",\r\n    ground_truth_signal: groundTruthSignal,\r\n    pipeline_decision: escalate ? \"ESCALATE_TO_HUMAN\" : \"AUTO_RESOLVE\",\r\n    agrees_with_ground_truth: agreesWithGroundTruth,\r\n  };\r\n}\n\nconst ticket = $input.item.json;\nconst ground_truth = computeGroundTruthAgreement(ticket, ticket.escalate);\nreturn { json: { ...ticket, ground_truth } };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000018",
      "name": "Compute Ground-Truth Agreement",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4480,
        -140
      ],
      "notesInFlow": true,
      "notes": "Phase 5 (spec Section 8): compares the pipeline's decision against CFPB's own outcome fields. Only company_response and timely exist in the live API -- disputed flag is confirmed unavailable, not silently dropped. Reported as a directional agreement signal, never accuracy."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "b2f7d3a1-0000-4000-8000-000000000015-cond",
              "leftValue": "={{ $json.escalate }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000015",
      "name": "IF: Escalate?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        4700,
        -140
      ],
      "notesInFlow": true,
      "notes": "Deterministic gate (spec Section 7) -- compound OR over five independent signals computed upstream, not a fifth agent call."
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const t = $input.item.json;\nreturn {\n  json: {\n    complaint_id: t.complaint_id, company: t.company, product: t.product, issue: t.issue, sub_issue: t.sub_issue,\n    decision: \"ESCALATE_TO_HUMAN\",\n    crm_summary: { account_tier: t.crm.account_tier, tenure_years: t.crm.tenure_years, special_population_flag: t.crm.special_population_flag },\n    agents: {\n      agent1: { tool_used: t.agent1_tool_used, output: t.agent1_output, tool_result: t.agent1_tool_result || null },\n      agent2: {\n        broader_crm_lookup_used: t.agent2_broader_crm_lookup_used, output: t.agent2_output,\n        regulation_tool_result: t.agent2_regulation_tool_result, crm_tool_result: t.agent2_crm_tool_result || null,\n      },\n      agent3: { tool_used: t.agent3_tool_used, output: t.agent3_output, tool_result: t.agent3_tool_result || null },\n      agent4: { tool_used: t.agent4_tool_used, output: t.agent4_output, tool_result: t.agent4_tool_result || null },\n    },\n    escalation_signals: t.escalation_signals,\n    ground_truth: t.ground_truth,\n  },\n};"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000016",
      "name": "Final: Escalate to Human Queue",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4920,
        -260
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const t = $input.item.json;\nreturn {\n  json: {\n    complaint_id: t.complaint_id, company: t.company, product: t.product, issue: t.issue, sub_issue: t.sub_issue,\n    decision: \"AUTO_RESOLVE\",\n    draft: t.agent3_output ? t.agent3_output.draft : null,\n    agents: {\n      agent1: { tool_used: t.agent1_tool_used, output: t.agent1_output, tool_result: t.agent1_tool_result || null },\n      agent2: {\n        broader_crm_lookup_used: t.agent2_broader_crm_lookup_used, output: t.agent2_output,\n        regulation_tool_result: t.agent2_regulation_tool_result, crm_tool_result: t.agent2_crm_tool_result || null,\n      },\n      agent3: { tool_used: t.agent3_tool_used, output: t.agent3_output, tool_result: t.agent3_tool_result || null },\n      agent4: { tool_used: t.agent4_tool_used, output: t.agent4_output, tool_result: t.agent4_tool_result || null },\n    },\n    escalation_signals: t.escalation_signals,\n    ground_truth: t.ground_truth,\n  },\n};"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000017",
      "name": "Final: Auto-Resolve",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4920,
        -20
      ]
    },
    {
      "parameters": {
        "mode": "append",
        "numberInputs": 2
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000020",
      "name": "Merge: Final Decision Rows",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        5030,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "// Flattens a final record into single-level columns for the Google Sheets\n// node that follows (spec Section 11). complaint_id is the dedup key --\n// the Sheets node's Append-or-Update operation matches on it, so a\n// re-processed ticket (the date-level watermark overlap noted since\n// Phase 1) updates its existing row instead of duplicating it.\nfunction flattenForSheets(record) {\r\n  const a1 = record.agents.agent1.output || {};\r\n  // Agent 1's output is either {issue, severity, confidence} (clean match)\r\n  // or {issues: [...], primary_issue} (Ticket C's compound-issue schema) --\r\n  // resolve to the primary issue's own severity/confidence either way.\r\n  let agent1Severity = a1.severity;\r\n  let agent1Confidence = a1.confidence;\r\n  if (a1.issues) {\r\n    const primary = a1.issues.find((i) => i.issue === a1.primary_issue);\r\n    agent1Severity = primary ? primary.severity : null;\r\n    agent1Confidence = primary ? primary.confidence : null;\r\n  }\r\n\r\n  const a2 = record.agents.agent2.output || {};\r\n  const a3 = record.agents.agent3.output || {};\r\n  const a4 = record.agents.agent4.output || {};\r\n  const sig = record.escalation_signals || {};\r\n  const gt = record.ground_truth || {};\r\n\r\n  return {\r\n    complaint_id: record.complaint_id,\r\n    company: record.company,\r\n    product: record.product,\r\n    issue: record.issue,\r\n    sub_issue: record.sub_issue || \"\",\r\n    decision: record.decision,\r\n    agent1_severity: agent1Severity || \"\",\r\n    agent1_confidence: agent1Confidence ?? \"\",\r\n    agent1_tool_used: record.agents.agent1.tool_used,\r\n    agent2_applicable_regulation: a2.applicable_regulation || \"\",\r\n    agent2_citation: a2.citation || \"\",\r\n    agent2_special_population_flag: a2.special_population_flag ?? \"\",\r\n    agent2_broader_crm_lookup_used: record.agents.agent2.broader_crm_lookup_used,\r\n    agent3_cites_regulation: a3.cites_regulation ?? \"\",\r\n    agent3_draft: a3.draft || \"\",\r\n    agent4_confidence: a4.confidence ?? \"\",\r\n    agent4_requires_human: a4.requires_human ?? \"\",\r\n    agent4_reason: a4.reason || \"\",\r\n    escalate_requires_human: sig.requiresHuman ?? \"\",\r\n    escalate_low_confidence: sig.lowConfidence ?? \"\",\r\n    escalate_high_risk_issue: sig.isHighRiskIssue ?? \"\",\r\n    escalate_repeat_complainant: sig.isRepeatComplainant ?? \"\",\r\n    escalate_high_value_account: sig.isHighValueAccount ?? \"\",\r\n    escalate_monetary_threshold: sig.exceedsMonetaryThreshold ?? \"\",\r\n    escalate_stated_monetary_exposure: sig.statedMonetaryExposure ?? \"\",\r\n    cfpb_company_response: gt.cfpb_company_response || \"\",\r\n    cfpb_timely: gt.cfpb_timely || \"\",\r\n    cfpb_disputed_flag: gt.cfpb_disputed_flag || \"\",\r\n    ground_truth_signal: gt.ground_truth_signal || \"\",\r\n    agrees_with_ground_truth: gt.agrees_with_ground_truth ?? \"\",\r\n    crm_account_tier: record.crm_summary ? record.crm_summary.account_tier : \"\",\r\n    crm_tenure_years: record.crm_summary ? record.crm_summary.tenure_years : \"\",\r\n    crm_special_population_flag: record.crm_summary ? record.crm_summary.special_population_flag : \"\",\r\n  };\r\n}\n\nconst record = $input.item.json;\nreturn { json: flattenForSheets(record) };"
      },
      "id": "b2f7d3a1-0000-4000-8000-000000000019",
      "name": "Prepare Row for Google Sheets",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        5140,
        -140
      ],
      "notesInFlow": true,
      "notes": "Flattens either final-record shape into single-level columns. complaint_id is the dedup key the next node matches on."
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "value": "REPLACE_WITH_YOUR_GOOGLE_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Sheet1",
          "mode": "list",
          "cachedResultName": "Sheet1"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "complaint_id"
          ],
          "schema": []
        },
        "options": {}
      },
      "id": "b2f7d3a1-0000-4000-8000-00000000001a",
      "name": "Google Sheets: Log Decision",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        5360,
        -140
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "notes": "Spec Section 11 -- Append-or-Update, matchingColumns=[complaint_id]. This is the actual dedup mechanism for the date-level watermark overlap noted since Phase 1: a re-processed complaint_id updates its existing row rather than duplicating it. REPLACE the documentId/sheetName/credentials placeholders before running -- untested against live n8n/Sheets, see the code comment above googleSheetsNode()."
    }
  ],
  "connections": {
    "Schedule Trigger (15 min)": {
      "main": [
        [
          {
            "node": "Get Watermark",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Get Watermark",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Watermark": {
      "main": [
        [
          {
            "node": "CFPB Complaint Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CFPB Complaint Search": {
      "main": [
        [
          {
            "node": "Cap Batch & Advance Watermark",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cap Batch & Advance Watermark": {
      "main": [
        [
          {
            "node": "Generate Synthetic CRM Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Synthetic CRM Record": {
      "main": [
        [
          {
            "node": "Merge: Fixture or Live Tickets",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Load Fixture Tickets": {
      "main": [
        [
          {
            "node": "Merge: Fixture or Live Tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Fixture or Live Tickets": {
      "main": [
        [
          {
            "node": "Route: Fixture or Live?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Fixture or Live?": {
      "main": [
        [
          {
            "node": "IF: Is Fixture Ticket?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Is Fixture Ticket?": {
      "main": [
        [
          {
            "node": "Agent 1: Mock Classification Decision",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Real Agent 1: Classification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Real Agent 1: Classification": {
      "main": [
        [
          {
            "node": "Parse: Real Agent 1 Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse: Real Agent 1 Response": {
      "main": [
        [
          {
            "node": "IF: Real Agent 1 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Real Agent 1 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: Real CFPB Taxonomy Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Real Agent 2",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Real CFPB Taxonomy Lookup": {
      "main": [
        [
          {
            "node": "Merge: Pre-Real Agent 2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Real Agent 2": {
      "main": [
        [
          {
            "node": "Real Agent 2: Research",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Real Agent 2: Research": {
      "main": [
        [
          {
            "node": "Parse: Real Agent 2 Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse: Real Agent 2 Response": {
      "main": [
        [
          {
            "node": "Tool: Real Special Population Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tool: Real Special Population Check": {
      "main": [
        [
          {
            "node": "Tool: Real Regulation Index Lookup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tool: Real Regulation Index Lookup": {
      "main": [
        [
          {
            "node": "IF: Real Agent 2 Broader CRM Lookup Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Real Agent 2 Broader CRM Lookup Used?": {
      "main": [
        [
          {
            "node": "Tool: Real CRM Broader Context Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Real Agent 3",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Real CRM Broader Context Lookup": {
      "main": [
        [
          {
            "node": "Merge: Pre-Real Agent 3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Real Agent 3": {
      "main": [
        [
          {
            "node": "Real Agent 3: Drafting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Real Agent 3: Drafting": {
      "main": [
        [
          {
            "node": "Parse: Real Agent 3 Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse: Real Agent 3 Response": {
      "main": [
        [
          {
            "node": "IF: Real Agent 3 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Real Agent 3 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: Real Exact Regulation Clause Fetch",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Real Agent 4",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Real Exact Regulation Clause Fetch": {
      "main": [
        [
          {
            "node": "Merge: Pre-Real Agent 4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Real Agent 4": {
      "main": [
        [
          {
            "node": "Real Agent 4: QA / Escalation-Scoring",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Real Agent 4: QA / Escalation-Scoring": {
      "main": [
        [
          {
            "node": "Parse: Real Agent 4 Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse: Real Agent 4 Response": {
      "main": [
        [
          {
            "node": "IF: Real Agent 4 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Real Agent 4 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: Real Re-verify Clause & CRM Fact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Real Escalation Signals",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Real Re-verify Clause & CRM Fact": {
      "main": [
        [
          {
            "node": "Merge: Pre-Real Escalation Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Real Escalation Signals": {
      "main": [
        [
          {
            "node": "Merge: Test/Product Final",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Escalation Signals": {
      "main": [
        [
          {
            "node": "Merge: Test/Product Final",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge: Test/Product Final": {
      "main": [
        [
          {
            "node": "Compute Escalation Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent 1: Mock Classification Decision": {
      "main": [
        [
          {
            "node": "IF: Agent 1 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Agent 1 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: CFPB Taxonomy Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Agent 2",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: CFPB Taxonomy Lookup": {
      "main": [
        [
          {
            "node": "Merge: Pre-Agent 2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Agent 2": {
      "main": [
        [
          {
            "node": "Agent 2: Mock Research Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent 2: Mock Research Decision": {
      "main": [
        [
          {
            "node": "Tool: Special Population Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tool: Special Population Check": {
      "main": [
        [
          {
            "node": "Tool: Regulation Index Lookup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tool: Regulation Index Lookup": {
      "main": [
        [
          {
            "node": "IF: Agent 2 Broader CRM Lookup Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Agent 2 Broader CRM Lookup Used?": {
      "main": [
        [
          {
            "node": "Tool: CRM Broader Context Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Agent 3",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: CRM Broader Context Lookup": {
      "main": [
        [
          {
            "node": "Merge: Pre-Agent 3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Agent 3": {
      "main": [
        [
          {
            "node": "Agent 3: Mock Drafting Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent 3: Mock Drafting Decision": {
      "main": [
        [
          {
            "node": "IF: Agent 3 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Agent 3 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: Exact Regulation Clause Fetch",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Agent 4",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Exact Regulation Clause Fetch": {
      "main": [
        [
          {
            "node": "Merge: Pre-Agent 4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Pre-Agent 4": {
      "main": [
        [
          {
            "node": "Agent 4: Mock QA Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent 4: Mock QA Decision": {
      "main": [
        [
          {
            "node": "IF: Agent 4 Tool Used?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Agent 4 Tool Used?": {
      "main": [
        [
          {
            "node": "Tool: Re-verify Clause & CRM Fact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge: Pre-Escalation Signals",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Tool: Re-verify Clause & CRM Fact": {
      "main": [
        [
          {
            "node": "Merge: Pre-Escalation Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Escalation Signals": {
      "main": [
        [
          {
            "node": "Compute Ground-Truth Agreement",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Ground-Truth Agreement": {
      "main": [
        [
          {
            "node": "IF: Escalate?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Escalate?": {
      "main": [
        [
          {
            "node": "Final: Escalate to Human Queue",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Final: Auto-Resolve",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Final: Escalate to Human Queue": {
      "main": [
        [
          {
            "node": "Merge: Final Decision Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Final: Auto-Resolve": {
      "main": [
        [
          {
            "node": "Merge: Final Decision Rows",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge: Final Decision Rows": {
      "main": [
        [
          {
            "node": "Prepare Row for Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Row for Google Sheets": {
      "main": [
        [
          {
            "node": "Google Sheets: Log Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}