@privacyscrubber/mcp-server 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ps-pii-engine.js CHANGED
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * @generated by scripts/sync-pii-engine.js — DO NOT EDIT DIRECTLY
3
+ * Source of truth: src/core/pii-engine-core.js
4
+ *
2
5
  * PrivacyScrubber Shared PII Engine
3
6
  * Shared between Website Worker, Chrome Extension, and MCP Server.
4
7
  * Responsible for running Regex checks, overlap resolution, and reverse scrubbing.
@@ -25,20 +28,16 @@ let DEVOPS_SECRETS = [
25
28
  { name: 'Hash / Hex Key (32-64 chars)', type: 'SECRET', regex: /\b[a-fA-F0-9]{32,64}\b/g },
26
29
  { name: 'CVE Identifier', type: 'SECRET', regex: /\bCVE-\d{4}-\d{4,}\b/gi },
27
30
  { name: 'Cryptographic Hash', type: 'SECRET', regex: /\b(?:MD5|SHA1|SHA256)[:\s][a-f0-9]{32,64}\b/gi },
28
- { name: 'Database/API Secret', type: 'SECRET', regex: /\b(?:DB|POSTGRES|REDIS|MYSQL|AWS|SECRET|PASSWORD|TOKEN|API|KEY)[A-Z0-9_]*\s*[:=]\s*[^\s"']+\b/gi },
31
+ { name: 'Database/API Secret', type: 'SECRET', regex: /\b(?:DB|POSTGRES|REDIS|MYSQL|AWS|SECRET|PASSWORD|TOKEN|API)[A-Z0-9_]*\s*[:=]\s*[^\s"']+\b|\b(?:API_KEY|SECRET_KEY|PRIVATE_KEY|ACCESS_KEY|AUTH_KEY|ENCRYPTION_KEY)\s*[:=]\s*[^\s"']+\b/gi },
29
32
  { name: 'Proprietary IP / Confidential', type: 'SECRET', regex: /\b(?:CONFIDENTIAL|PROPRIETARY|TRADE SECRET|DO NOT DISTRIBUTE|INTERNAL USE ONLY)\b/gi },
30
33
  { name: 'Private Cryptographic Key', type: 'SECRET', regex: /-----BEGIN (?:RSA |EC |PGP |DSA )?PRIVATE KEY-----/g }
31
34
  ];
32
35
 
33
36
  let REGEX_RULES = [
34
- ...DEVOPS_SECRETS,
35
37
  // Emails
36
38
  { type: 'EMAIL', regex: /\b[a-zA-Z0-9._%+-]{1,64}@[a-zA-Z0-9.-]{1,255}\.[a-zA-Z]{2,}\b/g },
37
39
 
38
- // Financial Data (PCI-DSS, Bank Accounts, Direct Deposits, Cards, IBAN, SWIFT, Routing Numbers)
39
- { type: 'FINANCIAL', regex: /\b[A-Z]{4}(?:AD|AE|AF|AG|AI|AL|AM|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BQ|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CW|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EE|EG|EH|ER|ES|ET|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|SS|ST|SV|SX|SY|SZ|TC|TD|TF|TG|TJ|TK|TL|TM|TN|TO|TR|TT|TV|TW|TZ|UA|UG|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|ZA|ZM|ZW)[A-Z2-9][A-NP-Z0-9](?:[A-Z0-9]{3})?\b/g },
40
- { type: 'FINANCIAL', regex: /\b[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}[a-zA-Z0-9]{0,16}\b/g },
41
- { type: 'FINANCIAL', regex: /\bPORTFOLIO[-_][A-Z0-9]{5,}\b/gi },
40
+ // Financial Data (Cards, Crypto, Direct Deposit & Bank Routing)
42
41
  { type: 'FINANCIAL', regex: /\b(?:\d[ -]?){13,19}\b/g },
43
42
  { type: 'FINANCIAL', regex: /\b(?:1|3|bc1)[a-zA-HJ-NP-Z0-9]{25,39}\b/g },
44
43
  { type: 'FINANCIAL', regex: /\b0x[a-fA-F0-9]{40}\b/g },
@@ -46,73 +45,31 @@ let REGEX_RULES = [
46
45
  { type: 'FINANCIAL', regex: /\b(?:Account|Acct|Checking|Savings|Direct\s+Deposit)\s*(?:#|ID|No\.?|Number)?[:\s#]*(?:[\*xX•.-]{3,}\d{2,6}|\d{4}[-\s]?\d{4}[-\s]?\d{2,6})\b/gi },
47
46
  { type: 'FINANCIAL', regex: /\b(?:ABA|Routing|RTN)\s*(?:#|ID|No\.?|Number)?[:\s#]*\d{9}\b/gi },
48
47
 
49
- // Legal & Court
50
- { type: 'LEGAL', regex: /\bCASE[-_][A-Z0-9_-]{4,}\b/gi },
51
- { type: 'LEGAL', regex: /\bMATTER[-_][A-Z0-9_-]{4,}\b/gi },
52
- { type: 'PRIVILEGE', regex: /ATTORNEY[- ]CLIENT[- ]PRIVILEGE/gi },
53
-
54
48
  // Professional IDs & Organizations
55
- { type: 'NAME', isContextName: true, regex: /\b(?:[A-Z][A-Za-z0-9&.,'-]*[ \t\xA0]+){1,5}(?:Inc\.?|LLC|Corp\.?|Corporation|Ltd\.?|Limited|Co\.?|Company|Group|Holdings|Solutions|Services|Technologies|Logistics|Industries|Capital|Bank|Partners|LLP|PLLC)(?:\s+(?:LLC|Inc\.?|Corp\.?|Ltd\.?|USA|Group))?\b/g },
49
+ { type: 'NAME', isContextName: true, isCorporateName: true, regex: /\b(?:[A-Z][A-Za-z0-9&.,'-]*[ \t\xA0]+){1,5}(?:Inc\.?|LLC|Corp\.?|Corporation|Ltd\.?|Limited|Co\.?|Company|Group|Holdings|Solutions|Services|Technologies|Logistics|Industries|Capital|Bank|Partners|LLP|PLLC)(?:\s+(?:LLC|Inc\.?|Corp\.?|Ltd\.?|USA|Group))?\b/g },
56
50
  { type: 'ID', regex: /\b(?:Employee|Emp|EE|Worker|Staff|File|Badge|Member|Advisor|Producer|Agent|Borrower)\s*(?:#|ID|No\.?|Number)[:\s#]*[A-Z0-9-]{3,15}\b/gi },
57
- { type: 'ID', regex: /\b(?:Pay\s+Group|Cost\s+Center|Dept|Department)[:\s#]*[A-Za-z0-9_-]{2,30}\b/gi },
58
- { type: 'ID', regex: /(?:\b(?:Box\s+d\b|d\.\s*(?:Control|#)?|d\s+Control)\s*(?:number|no\.?|#|num)?[:\s#]*|\bControl\s*(?:number|no\.?|#|num)[:\s#]*|\bControl[:#]\s*)([A-Za-z0-9-]{3,30})/gi },
51
+ { type: 'ID', regex: /\b(?:Pay\s+Group[:#\s]+[A-Za-z0-9_-]{2,30}|(?:Cost\s+Center|Dept|Department)[:#\s]+[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*)\b/gi },
52
+ { type: 'ID', regex: /(?:\b(?:Box\s+d\b|d\.\s*(?:Control|#)?|d\s+Control)\s*(?:Control\s+)?(?:number|no\.?|#|num)?[:\s#]+|\bControl\s*(?:number|no\.?|#|num)?[:\s#]+|\bControl[:#]\s*)([A-Za-z0-9-]{3,30})/gi },
59
53
  { type: 'ID', regex: /\bEEID[ -]?\d{4,}\b/gi },
60
- { type: 'ID', regex: /\bRESUME[-_]?[A-Z0-9]{4,}\b/gi },
61
- { type: 'ID', regex: /\bLEAD[-_][A-Z0-9]{5,}\b/gi },
62
- { type: 'ID', regex: /\bCAMPAIGN[-_][A-Z0-9]{4,}\b/gi },
63
- { type: 'ID', regex: /\bDEAL[-_][A-Z0-9]{4,}\b/gi },
64
- { type: 'ID', regex: /\bENTITY[-_][0-9]{4,}\b/gi },
65
- { type: 'ID', regex: /\bOPPORTUNITY[-_][A-Z0-9]{5,}\b/gi },
66
- { type: 'ID', regex: /\bPROSPECT[-_][A-Z0-9]{5,}\b/gi },
67
- { type: 'ID', regex: /\bTICKET[-_][A-Z0-9]{5,}\b/gi },
68
- { type: 'ID', regex: /\bZENDESK[-_][0-9]{4,}\b/gi },
69
54
  { type: 'ID', regex: /\bEMP[-_]\d{3,}\b/gi },
70
- { type: 'ID', regex: /\bLIS[-]?\d{6,}\b/gi },
71
- { type: 'ID', regex: /\bPARCEL[-]?\d{5,}\b/gi },
72
- { type: 'ID', regex: /\bAGENT[-_][A-Z0-9]{4,}\b/gi },
73
- { type: 'ID', regex: /\bTASK[-_][A-Z0-9]{5,}\b/gi },
74
- { type: 'ID', regex: /\bSTUDENT[-_][0-9]{5,}\b/gi },
75
- { type: 'ID', regex: /\bCOURSE[-_][A-Z0-9]{4,}\b/gi },
76
- { type: 'ID', regex: /\bINSTANCE[-_]ID[-_][a-z0-9-]{10,}\b/gi },
77
- { type: 'ID', regex: /\bENV[-_][A-Z0-9]{3,}\b/gi },
78
- { type: 'ID', regex: /\bTENANT[-_]ID[-_][0-9]{4,}\b/gi },
79
-
80
- // Insurance & Health Plan IDs
81
- { type: 'ID', regex: /\b(?:BCB|BCBS|AETNA|CIGNA|UHC|HUMANA|MEDICARE|MEDICAID)[-_A-Za-z0-9]+\b/gi },
82
- { type: 'ID', regex: /\b(?:Insurance\s+(?:ID|No\.?|Number|#)|Policy(?:\s*(?:ID|No\.?|Number|#)|[:#])|Member\s*(?:ID|No\.?|Number|#|[:#])|Subscriber\s*(?:ID|No\.?|Number|#|[:#])|Group\s*(?:ID|No\.?|Number|#|[:#])|Plan\s*(?:ID|No\.?|Number|#|[:#])|Health(?:\s+Plan)?\s*(?:ID|No\.?|Number|#)|Rx\s*(?:ID|No\.?|Number|Group|BIN|PCN|#))[:\s#]*([A-Za-z0-9-]+)/gi },
83
- { type: 'ID', regex: /\b(?:Health\s+Plan(?:\s+Beneficiary)?|Beneficiary(?:\s+(?:No\.?|Number|ID|Num|#))?|HPN)[:\s#]+([A-Za-z0-9-]+)/gi },
84
- { type: 'ID', regex: /\bHPN[-_][A-Za-z0-9-]+\b/gi },
85
-
86
- // Addresses & Locations
55
+
87
56
  { type: 'ADDRESS', isContextAddress: true, regex: /(?:(?:\bBox\s+f\b|\bf\.\s*|\bf\s+(?=Employee))\s*(?:Employee(?:'s)?\s*)?(?:address[,\s]+and\s+ZIP\s+code|address)?|(?:Employee(?:'s)?\s+address[,\s]+and\s+ZIP\s+code))[\s:#]*([A-Za-z0-9#.,\s-]{4,55}?)(?=\r?\n|$|\s{3,}|\t|Box|\d+\b|1\b|2\b|Wages|Federal|Social|Medicare)/gi },
88
57
  { type: 'ADDRESS', isContextAddress: true, regex: /(?:(?:Borrower(?:'s)?|Co-Borrower(?:'s)?|Employee(?:'s)?|Employer(?:'s)?|Home|Mailing|Property|Physical)\s+address)[\s:#]+([A-Za-z0-9#.,\s-]{4,55}?)(?=\r?\n|$|\s{3,}|\t|City|State|ZIP|SSN|EIN|Phone|Box|\d+\b)/gi },
89
- { type: 'ADDRESS', regex: /\b\d{1,6}[ \t\xA0]+(?:[A-Za-z0-9.-]+[ \t\xA0]+){1,4}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Dr|Drive|Way|Ct|Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Hwy|Highway|Cir|Circle|Trl|Trail|Loop|Row|Pike|Box|PO Box|P\.O\.[ \t\xA0]*Box)\b(?:[ \t\xA0]*,?[ \t\xA0]*(?:Apt|Apartment|Suite|Ste|Unit|#|Fl|Floor|Bldg|Building)\.?[ \t\xA0]*[A-Za-z0-9-]+)?/gi },
58
+ { type: 'ADDRESS', regex: /\b\d{1,6}[ \t\xA0]+(?:[A-Za-z0-9.-]+[ \t\xA0]+){0,4}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Dr|Drive|Way|Ct|(?<!District |Supreme |Circuit |Appellate |Bankruptcy |High |Federal |Trial )Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Hwy|Highway|Cir|Circle|Trl|Trail|Loop|Row|Pike|Bishopsgate|Gate|Walk|Close|Hill|Crescent|Gardens|Grove|Mews|Yard|PO Box|P\.O\.[ \t\xA0]*Box)\b(?:[ \t\xA0]*,?[ \t\xA0]*(?:Apt|Apartment|Suite|Ste|Unit|#|Fl|Floor|Bldg|Building)\.?[ \t\xA0]*[A-Za-z0-9-]+)?/gi },
90
59
  { type: 'ADDRESS', regex: /\b(?:P\.?O\.?[ \t\xA0]*Box|PO[ \t\xA0]*Box)[ \t\xA0]+\d{1,6}\b/gi },
91
60
  { type: 'ADDRESS', regex: /\b[A-Za-z][a-zA-Z\s.-]{1,25},?\s+(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)\s+\d{5}(?:-\d{4})?\b/g },
92
61
  { type: 'ADDRESS', regex: /\b(?:ZIP|Postal|Code)?\s*(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)\s+\d{5}(?:-\d{4})?\b/g },
93
62
  { type: 'ADDRESS', regex: /\b\d{5}-\d{4}\b/g },
94
- { type: 'LOCATION', regex: /\b[A-Za-z][a-zA-Z .'-]{1,25}(?:,\s*(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)|\s+(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR))\b/g },
95
-
96
- // PHI & Medical
97
- { type: 'PHI', regex: /\b(?:MRN|Patient ID|Medical Record (?:No\.?|Num(?:ber)?|#)|Patient (?:No\.?|Num(?:ber)?|#))[\s:#]+([A-Za-z0-9-]+)/gi },
98
- { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9-]{4,}\b/gi },
99
- { type: 'ID', regex: /\b(?:NPI|National Provider Identifier)[:\s#]*(\d{10})\b/gi },
100
- { type: 'ID', regex: /\b(?:Device\s+(?:Identifier|ID|Serial|No\.?|Number)|UDI)[:\s#]+([A-Za-z0-9-]+)/gi },
101
- { type: 'ID', regex: /\bUDI[-_][A-Za-z0-9-]+\b/gi },
102
- { type: 'ID', regex: /\b(?:Vehicle\s+(?:Serial|ID|Identification(?:\s+Number)?|No\.?|Number)|VIN)[:\s#]+([A-Za-z0-9-]+)/gi },
103
- { type: 'ID', regex: /\bVIN[-_][A-Za-z0-9-]+\b/gi },
104
- { type: 'PHI', regex: /\b[A-TV-Z]\d{2}[. ]?\d[A-Z0-9]?\b/g },
105
- { type: 'PHI', regex: /\b[A-Z]{2,3}\d{6,8}\b/g },
106
- { type: 'PHI', regex: /\bNHS[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}\b/gi },
107
-
108
- // Copyrights
109
- { type: 'COPYRIGHT', regex: /\bPROJECT[-_][A-Z0-9]{5,}\b/gi },
110
- { type: 'COPYRIGHT', regex: /\b(DRAFT|ASSET|SCRIPT)[-_][0-9]{4,}\b/gi },
63
+ // SSN / National IDs
64
+ { type: 'ID', regex: /\b\d{3}-\d{2}-\d{4}\b/g },
65
+ { type: 'ID', regex: /(?<=^|[^\w*])(?:\*{3}|X{3}|x{3}|\*{2}|X{2}|x{2})[ -]?(?:\*{2}|X{2}|x{2})\b/gi },
66
+ { type: 'ID', regex: /(?<=^|[^\w*])(?:\*{3}|X{3}|x{3}|\*{2}|X{2}|x{2})[ -]?(?:\*{2}|X{2}|x{2})[ -]?\d{4}\b/g },
67
+ { type: 'ID', regex: /\b\d{2}-\d{7}\b/g },
68
+ { type: 'ID', regex: /\b(?:HICN|MBI)[:\s#]*([0-9][A-Za-z][0-9A-Za-z][0-9]-[A-Za-z][0-9A-Za-z][0-9]-[A-Za-z0-9]{4})\b/gi },
69
+ { type: 'ID', regex: /\b[1-9][A-Za-z][0-9A-Za-z][0-9]-[A-Za-z][0-9A-Za-z][0-9]-[A-Za-z0-9]{4}\b/gi },
70
+ { type: 'LOCATION', regex: /\b[A-Za-z][a-zA-Z .'-]{1,25},\s*(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)\b/g },
111
71
 
112
72
  // General Privacy, Dates & Secrets
113
- { type: 'ID', regex: /\b(?:GDPR|HIPAA|CCPA|SOC2)[-_]AUDIT[-_]\d{4}\b/gi },
114
- { type: 'ID', regex: /\bPOLICY[-_][A-Z0-9]{5,}\b/gi },
115
- { type: 'ID', regex: /\bGRADE[S]?\s*:\s*[A-DF][+-]?\b/gi },
116
73
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
117
74
  { type: 'SECRET', regex: /\b(?:PASSWORD|PWD|SECRET)\s*[:=]\s*["']?[\S]{4,}["']?/gi },
118
75
 
@@ -129,13 +86,14 @@ let REGEX_RULES = [
129
86
  { type: 'IP', regex: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g },
130
87
  { type: 'IP', regex: /\b(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}\b/g },
131
88
  { type: 'ID', regex: /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/g },
132
- { type: 'ID', regex: /(?:\B\/|\b[a-zA-Z]:\\)(?:[\w.-]+[\/\\])*[\w.-]+\b/g },
89
+ { type: 'ID', regex: /(?<![:/A-Za-z0-9])(?:\/[a-zA-Z0-9_.-]+(?:[\/\\][a-zA-Z0-9_.-]+)+|\b[a-zA-Z]:\\[\w.-]+(?:\\[\w.-]+)*)/g },
133
90
  { type: 'ID', regex: /\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}(?::\d{2})?)?\b/g },
134
91
  { type: 'ID', regex: /\b\d{4}-\d{2}-\d{2}\b/g },
135
92
  { type: 'ID', regex: /\b\d{2}\/\d{2}\/\d{4}\b/g },
136
93
 
137
94
  // Phone Numbers
138
95
  { type: 'PHONE', regex: /(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g },
96
+ { type: 'PHONE', regex: /\+\d{1,3}[ \t.-]+(?:\(?\d{1,4}\)?[ \t.-]+)?\d{2,8}(?:[ \t.-]+\d{2,8}){0,4}\b/g },
139
97
  { type: 'PHONE', regex: /\+?[1-9]\d{1,3}[\s.-]\(?\d{1,4}\)?[\s.-]\d{2,4}[\s.-]\d{4}/g },
140
98
  { type: 'PHONE', regex: /(?:\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}\b/g },
141
99
  { type: 'PHONE', regex: /\b(?:\d{3}[-.\s]\d{4}|\(\d{3}\)\s??\d{3}[-.\s]??\d{4}|\d{3}[-.\s]??\d{3}[-.\s]??\d{4})\b/g },
@@ -170,8 +128,8 @@ let REGEX_RULES = [
170
128
  { type: 'NAME', isContextName: true, regex: /(?:(?:Employee(?:'s)?|Borrower(?:'s)?|Co-Borrower(?:'s)?|Applicant(?:'s)?|Candidate(?:'s)?|Worker(?:'s)?|Taxpayer(?:'s)?|Spouse(?:'s)?|Person(?:'s)?)\s+)?(?:First\s+name(?:\s+(?:and|&)\s+initial)?|Given\s+name)[\s:#]+(?:\b|\b\s*)([A-Za-z0-9.\s'-]{2,30}?)(?=\r?\n|$|\s{3,}|\t|Last|Surname|Family|Suff|Box|Address|SSN|EIN)/gi },
171
129
  // Contextual Last Names (Last name, Surname, Family name)
172
130
  { type: 'NAME', isContextName: true, regex: /(?:(?:Employee(?:'s)?|Borrower(?:'s)?|Co-Borrower(?:'s)?|Applicant(?:'s)?|Candidate(?:'s)?|Worker(?:'s)?|Taxpayer(?:'s)?|Spouse(?:'s)?|Person(?:'s)?)\s+)?(?:Last\s+name|Surname|Family\s+name)[\s:#]+(?:\b|\b\s*)([A-Za-z'-]{2,30})/gi },
173
- // Contextual General Names (Employee, Borrower, Co-Borrower, Taxpayer, Spouse, Applicant, Candidate, Worker, Employer, Company, Insured, Patient, Client, etc.)
174
- { type: 'NAME', isContextName: true, regex: /(?:Employee(?:\s+Name)?|Employer(?:\s+Name)?|Borrower(?:\s+Name)?|Co-Borrower(?:\s+Name)?|Applicant(?:\s+Name)?|Candidate(?:\s+Name)?|Worker(?:\s+Name)?|Taxpayer(?:\s+Name)?|Spouse(?:\s+Name)?|Manager|Supervisor|Reporting To|Insured|Claimant|Patient|Client|Customer|Account Holder|Prepared By|Attention|Attn|Contact(?: Name)?|Child|Parent|Guardian|Relationship|Kin|Tenant|Landlord|Buyer|Seller|Plaintiff|Defendant|Testator)[\s:#]+(?:\b|\b\s*)([A-Za-z0-9&.,\s'-]{2,40}?)(?=\r?\n|$|\s{3,}|\t|Employee|Employer|Address|Phone|SSN|EIN|FEIN|Date|Pay|Rate|Tax|W-2|OMB|Copy|Box|Status)/gi },
131
+ // Contextual General Names (Employee, Principal Investigator, Physician, Doctor, etc.)
132
+ { type: 'NAME', isContextName: true, regex: /(?:(?:Employee|Employer|Borrower|Co-Borrower|Applicant|Candidate|Worker|Taxpayer|Spouse|Client|Customer|Patient|Claimant|Insured|Tenant|Landlord|Buyer|Seller|Plaintiff|Defendant|Testator|Author)\s+(?:Name|Full\s+Name)|(?:Principal\s+Investigator|Investigator|Physician|Doctor|Supervisor|Reporting\s+To|Prepared\s+By|Attention|Attn|Contact(?:\s+Person)?|Author)(?:\s+Name)?|(?:Employee|Employer|Borrower|Client|Customer|Patient|Claimant|Insured|Doctor|Attn|Signatory|Witness|Tenant|Landlord|Buyer|Seller|Plaintiff|Defendant|Author)\s*[:=#])[:\s#]*(?:\b|\b\s*)([A-Z\p{Lu}][A-Za-z0-9&.,\s'-]{1,35}?)(?=\r?\n|$|\s{3,}|\t|Employee|Employer|Address|Phone|SSN|EIN|FEIN|Date|Pay|Rate|Tax|W-2|OMB|Copy|Box|Status)/giu },
175
133
  // Box e shorthand
176
134
  { type: 'NAME', isContextName: true, regex: /\b(?:Box\s+e)\s*[:#-]\s*([A-Za-z0-9&.,\s'-]{2,40})/gi }
177
135
  ];
@@ -182,29 +140,54 @@ let PROFILE_RULES = {
182
140
  { type: 'LEGAL', regex: /\bCASE[-_][A-Z0-9_-]{4,}\b/gi },
183
141
  { type: 'LEGAL', regex: /\bMATTER[-_][A-Z0-9_-]{4,}\b/gi },
184
142
  { type: 'LEGAL', regex: /\b[A-Z]{2,4}[- ]?\d{2}[- ]?\d{4,}\b/g },
185
- { type: 'PRIVILEGE', regex: /ATTORNEY[- ]CLIENT[- ]PRIVILEGE/gi }
143
+ { type: 'PRIVILEGE', regex: /ATTORNEY[- ]CLIENT[- ]PRIVILEGE/gi },
144
+ { type: 'LEGAL', regex: /\b(?:BATES|PROD|PLTF|DEFT|CONF|EXHIBIT)[-_ ]?[A-Z0-9]{2,10}[-_ ]?\d{4,10}\b/gi },
145
+ { type: 'LEGAL', regex: /\b(?:\d{1,2}:)?\d{2,4}[-_ ]?(?:CV|CR|MDL|BK|MC|MISC|MJ|PO|CA|AP|PR)[-_ ][A-Z0-9_-]{3,15}\b/gi },
146
+ { type: 'ID', regex: /\b(?:STATE\s+BAR|BAR\s+(?:NO\.?|#|ID)|SBN|ATTORNEY\s+REG(?:ISTRATION)?)[:\s#-]*\d{4,8}\b/gi },
147
+ { type: 'LEGAL', regex: /\b(?:RETAINER|ENGAGEMENT|REPRESENTATION)[-_: ]*(?:AGREEMENT|ID|REF)?[:\s#-]*[A-Z0-9_-]{4,20}\b/gi },
148
+ { type: 'LEGAL', regex: /\bECLI:[A-Z]{2}:[A-Za-z0-9]{1,7}:\d{4}:[A-Za-z0-9.]{1,25}\b/g },
149
+ { type: 'ID', regex: /\bPCT\/[A-Z]{2}\d{4}\/\d{6}\b/g },
150
+ { type: 'ID', regex: /\b(?:TX|TXu|VA|VAu|PA|PAu|SR|SRu|SE|SEu|RE)\s*-?\d[-\d ]{5,9}\d\b/g }
186
151
  ],
187
152
  hr: [
188
153
  { type: 'NAME', isContextName: true, regex: /(?:Candidate|Applicant|Employee|Reporting To|Manager|Mentored by|Direct Report)[\s:]+([A-Z][a-z]*(?:\s+[A-Z][a-z]*)?)/g },
189
154
  { type: 'ID', regex: /\bEEID[ -]?\d{4,}\b/gi },
190
155
  { type: 'ID', regex: /\bEMP[-_]\d{3,}\b/gi },
191
156
  { type: 'ID', regex: /\bRESUME[-_]?[A-Z0-9]{4,}\b/gi },
157
+ { type: 'ID', regex: /\b(?:CAND|CANDIDATE|APPLICANT)[-_: ]+[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
158
+ { type: 'ID', regex: /\b(?:WKDY|WORKDAY)[-_: ]+[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
159
+ { type: 'ID', regex: /\b(?:WORKS\s+COUNCIL|BETRIEBSRAT)(?:\s+(?:REF|ID|NOTICE))?[:\s#-]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
160
+ { type: 'ID', regex: /\bPIP[-_: ]+[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
161
+ { type: 'ID', regex: /\b(?:SECURITY\s+)?BADGE[:\s#-]*\d{4,8}\b/gi },
192
162
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
193
163
  { type: 'DATE', regex: /\b(?:Graduated|Graduation|Class of)[:\s]+(?:(?:Spring|Summer|Fall|Winter)\s+)?(?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|January|February|March|April|June|July|August|September|October|November|December)\s+)?\d{4}\b/gi },
194
164
  { type: 'ID', regex: /(?:https?:\/\/)?(?:www\.)?linkedin\.com\/in\/[A-Za-z0-9_-]+/gi },
195
165
  { type: 'ID', regex: /(?:https?:\/\/)?(?:www\.)?github\.com\/[A-Za-z0-9_-]+/gi },
196
- { type: 'ADDRESS', regex: /\b\d{1,6}\s+(?:[A-Z0-9][a-zA-Z0-9-]*\s+){1,3}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Drive|Way|Ct|Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Highway|Hwy|Circle|Cir|Trail|Trl|Dr(?!\.?\s+[A-Z][a-z]+))\b/g }
166
+ { type: 'ADDRESS', regex: /\b\d{1,6}\s+(?:[A-Z0-9][a-zA-Z0-9-]*\s+){1,3}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Drive|Way|Ct|(?<!District |Supreme |Circuit |Appellate |Bankruptcy |High |Federal |Trial )Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Highway|Hwy|Circle|Cir|Trail|Trl|Dr(?!\.?\s+[A-Z][a-z]+))\b/g },
167
+ { type: 'ID', regex: /\b(?:AOID|Associate\s+ID)[:\s#]*([A-Z0-9]{8,12})\b/gi },
168
+ { type: 'ID', regex: /\b(?:E-Verify\s*(?:Case|Verification)?\s*(?:No\.?|#|Number)?)[:\s#]*(\d{12,15})\b/gi },
169
+ { type: 'ID', regex: /\b(?:EEOC\s*(?:Charge|Case)?\s*(?:No\.?|#|Number)?)[:\s#-]*(\d{2,3}-\d{4}-\d{5})\b/gi },
170
+ { type: 'ID', regex: /\b(?:A-?Number|USCIS\s*(?:#|No\.?))[:\s#]*(?:A[- ]?)?(\d{9})\b/gi }
197
171
  ],
198
172
  finance: [
199
173
  { type: 'FINANCIAL', regex: /\b[A-Z]{4}(?:AD|AE|AF|AG|AI|AL|AM|AO|AQ|AR|AS|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BQ|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CW|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EE|EG|EH|ER|ES|ET|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|SS|ST|SV|SX|SY|SZ|TC|TD|TF|TG|TJ|TK|TL|TM|TN|TO|TR|TT|TV|TW|TZ|UA|UG|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|ZA|ZM|ZW)[A-Z2-9][A-NP-Z0-9](?:[A-Z0-9]{3})?\b/g },
200
174
  { type: 'FINANCIAL', regex: /\b[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}[a-zA-Z0-9]{0,16}\b/g },
201
- { type: 'FINANCIAL', regex: /\bPORTFOLIO[-_][A-Z0-9]{5,}\b/gi }
175
+ { type: 'FINANCIAL', regex: /\bPORTFOLIO[-_][A-Z0-9_-]{5,}\b/gi },
176
+ { type: 'FINANCIAL', regex: /\b(?:Account|Acct|Brokerage|IRA|401k|403b|Roth|Trust|Custodial|Portfolio)\s*(?:Number|Num|No\.?|#)?[:\s#]+(?!GL[-_])([A-Za-z0-9-]{6,20})\b/gi },
177
+ { type: 'ID', regex: /\bCUSIP[:\s#]*([0-9A-Z]{9})\b/gi },
178
+ { type: 'ID', regex: /\bISIN[:\s#]*([A-Z]{2}[0-9A-Z]{9}[0-9])\b/gi },
179
+ { type: 'ID', regex: /\bSEDOL[:\s#]*([0-9B-DF-HJ-NP-TV-Z]{6}[0-9])\b/gi },
180
+ { type: 'FINANCIAL', regex: /\b(?:Routing|ABA|Transit)\s*(?:Number|Num|No\.?|#)?[:\s#]+(\d{9})\b/gi },
181
+ { type: 'ID', regex: /\b(?:FEIN|EIN|TIN|Tax\s*ID)[:\s#]*(\d{2}-\d{7})\b/gi },
182
+ { type: 'ID', regex: /\b(?:CRD|CIK|Advisor\s*ID|Broker\s*ID)[:\s#]*(\d{5,10})\b/gi },
183
+ { type: 'ID', regex: /\b(?:LEI|LEGAL[\s-]ENTITY[\s-]IDENTIFIER)[:\s#-]*[0-9A-Z]{20}\b/gi },
184
+ { type: 'ID', regex: /\bBBG[0-9A-Z]{9}\b/g }
202
185
  ],
203
186
  medical: [
204
187
  { type: 'PHI', regex: /\b(?:MRN|Patient ID|Medical Record (?:No\.?|Num(?:ber)?|#)|Patient (?:No\.?|Num(?:ber)?|#))[\s:#]+([A-Za-z0-9-]+)/gi },
205
188
  { type: 'DATE', regex: /\b(?:DOB|Date of Birth|BIRTHDAY)[\s:]+([0-9./-]{6,10})\b/gi },
206
- { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9-]{4,}\b/gi },
207
- { type: 'ID', regex: /\b(?:Insurance\s+(?:ID|No\.?|Number|#)|Policy(?:\s*(?:ID|No\.?|Number|#)|[:#])|Member\s*(?:ID|No\.?|Number|#|[:#])|Subscriber\s*(?:ID|No\.?|Number|#|[:#])|Group\s*(?:ID|No\.?|Number|#|[:#])|Plan\s*(?:ID|No\.?|Number|#|[:#])|Health(?:\s+Plan)?\s*(?:ID|No\.?|Number|#)|Rx\s*(?:ID|No\.?|Number|Group|BIN|PCN|#))[:\s#]*([A-Za-z0-9-]+)/gi },
189
+ { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9_-]{4,}\b/gi },
190
+ { type: 'ID', regex: /\b(?:Insurance\s+(?:ID|No\.?|Number|#)|Policy(?:\s*(?:ID|No\.?|Number|#)|[:#])|Member\s*(?:ID|No\.?|Number|#|[:#])|Subscriber\s*(?:ID|No\.?|Number|#|[:#])|Group\s*(?:ID|No\.?|Number|#|[:#])|Plan\s*(?:ID|No\.?|Number|#|[:#])|Health(?:\s+Plan)?\s*(?:ID|No\.?|Number|#)|Rx\s*(?:ID|No\.?|Number|Group|BIN|PCN|#))[:\s#]+([A-Za-z0-9-]{3,30})\b/gi },
208
191
  { type: 'ID', regex: /\b(?:Health\s+Plan(?:\s+Beneficiary)?|Beneficiary(?:\s+No\.?|\s+Number)?|HPN)[:\s#]+([A-Za-z0-9-]+)/gi },
209
192
  { type: 'ID', regex: /\bHPN[-_][A-Za-z0-9-]+\b/gi },
210
193
  { type: 'ID', regex: /\b(?:BCB|BCBS|AETNA|CIGNA|UHC|HUMANA|MEDICARE|MEDICAID)[-_A-Za-z0-9]+\b/gi },
@@ -213,138 +196,266 @@ let PROFILE_RULES = {
213
196
  { type: 'ID', regex: /\bUDI[-_][A-Za-z0-9-]+\b/gi },
214
197
  { type: 'ID', regex: /\b(?:Vehicle\s+(?:Serial|ID|Identification(?:\s+Number)?|No\.?|Number)|VIN)[:\s#]+([A-Za-z0-9-]+)/gi },
215
198
  { type: 'ID', regex: /\bVIN[-_][A-Za-z0-9-]+\b/gi },
216
- { type: 'PHI', regex: /\b[A-TV-Z]\d{2}[. ]?\d[A-Z0-9]?\b/g },
217
- { type: 'PHI', regex: /\b[A-Z]{2,3}\d{6,8}\b/g },
218
- { type: 'PHI', regex: /\bNHS[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}\b/gi }
199
+ { type: 'PHI', regex: /\b(?!NCT|INC|SEC|ISO|DOC|SOC|CPT)[A-Z]{2,3}\d{6,8}\b/g },
200
+ { type: 'PHI', regex: /\bNHS[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}\b/gi },
201
+ { type: 'ID', regex: /\b(?:DEA|DEA\s*(?:#|No\.?|Number|Reg(?:istration)?))[:\s#]*([A-Z][A-Z9]\d{7})\b/gi },
202
+ { type: 'PHI', regex: /\b(?:CHI|CHI\s*(?:No\.?|Number|#))[:\s#]*(\d{10})\b/gi },
203
+ { type: 'DATE', regex: /\b(?:Admission|Admit|Discharge|Service|DOS|Encounter|Death)\s*Date[:\s]+([0-9.\/-]{6,10})\b/gi },
204
+ { type: 'ID', regex: /\b(?:Patient|Encounter|Practitioner|Observation|Condition|Procedure|MedicationRequest|DiagnosticReport)\/[A-Za-z0-9\-.]{1,64}\b/g }
219
205
  ],
220
206
  security: [
221
- { type: 'SECRET', regex: /\b(?:INCIDENT|BREACH)[-_: ]?ID[-_: ]?[0-9]{4,10}\b/gi }
207
+ ...DEVOPS_SECRETS,
208
+ { type: 'SECRET', regex: /\b(?:INCIDENT|BREACH)[-_: ]?ID[-_: ]?[0-9]{4,10}\b/gi },
209
+ { type: 'ID', regex: /\b(?:APT|UNC|FIN|TA|LAPSUS\$|DEV|Storm)[-_ ]?\d{1,4}\b/gi },
210
+ { type: 'ID', regex: /\b(?:TA|T|M|G|S|C|DS)\d{4}(?:\.\d{3})?\b/g },
211
+ { type: 'SECRET', regex: /\bCVE-(?:1999|20\d{2})-\d{4,7}\b/gi },
212
+ { type: 'ID', regex: /\bCWE-\d{1,5}\b/gi },
213
+ { type: 'SECRET', regex: /\b(?:SIGMA|SPLUNK|ELK|QRADAR|SURICATA|SNORT)[-_ ]*(?:RULE|SIG|ID)?[:\s_-]*[A-Z0-9_-]{4,25}\b/gi },
214
+ { type: 'SECRET', regex: /\b(?:FW|FIREWALL|ACL|POLICY)[-_ ]*(?:RULE|SESSION|ID)[:\s#-]*[A-Za-z0-9_-]{4,25}\b/gi },
215
+ { type: 'SECRET', regex: /\b(?:sha256|SHA256)[:\s=]+[a-fA-F0-9]{64}\b/gi },
216
+ { type: 'SECRET', regex: /\b(?:md5|MD5)[:\s=]+[a-fA-F0-9]{32}\b/gi },
217
+ { type: 'SECRET', regex: /\b(?:sha1|SHA1)[:\s=]+[a-fA-F0-9]{40}\b/gi },
218
+ { type: 'SECRET', regex: /-----BEGIN OPENSSH PRIVATE KEY-----/g },
219
+ { type: 'SECRET', regex: /\b(?:GHSA|USN|RHSA|ALAS|VMSA|MS)[-_ ]?\d{2,4}[-_ ][A-Za-z0-9_-]{1,12}\b/gi },
220
+ { type: 'ID', regex: /\bhxxps?:\/\/[^\s"']+\b/gi },
221
+ { type: 'ID', regex: /\bCVSS:(?:3\.[01]|4\.0)\/[A-Z0-9:\/._ -]+\b/gi }
222
+ ],
223
+ dev: [
224
+ ...DEVOPS_SECRETS,
225
+ { type: 'SECRET', regex: /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp|mssql):\/\/[^\s"']+/gi },
226
+ { type: 'SECRET', regex: /\b(?:ghp|gho|ghu|ghs|ghr|glpat|npm|xox[baprs])[-_][A-Za-z0-9_-]{10,}\b/g },
227
+ { type: 'SECRET', regex: /\b(?:[rs]k)_(?:test|live)_[a-zA-Z0-9]{14,}\b/g },
228
+ { type: 'SECRET', regex: /\b(?:whsec|webhook[-_]secret|signing[-_]secret)[-_: =]*[a-zA-Z0-9_-]{16,}\b/gi },
229
+ { type: 'SECRET', regex: /\bBearer\s+eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\b/gi },
230
+ { type: 'SECRET', regex: /-----BEGIN (?:RSA |EC |PGP |DSA |OPENSSH )?PRIVATE KEY-----/g },
231
+ { type: 'IP', regex: /\b(?:(?:10\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])|192\.168)\.\d{1,3}\.\d{1,3}|localhost):\d{2,5}\b/g },
232
+ { type: 'SECRET', regex: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g },
233
+ { type: 'SECRET', regex: /\bAIza[0-9A-Za-z\-_]{35}\b/g },
234
+ { type: 'SECRET', regex: /\bsk-ant-(?:api03|admin01)-[a-zA-Z0-9_\-]{80,}\b/g },
235
+ { type: 'SECRET', regex: /\bsk-(?:proj-|admin-)?[a-zA-Z0-9_\-]{48,164}\b/g },
236
+ { type: 'SECRET', regex: /\bSG\.[a-zA-Z0-9_\-]{22}\.[a-zA-Z0-9_\-]{43}\b/g },
237
+ { type: 'SECRET', regex: /\b(?:AC|SK)[0-9a-fA-F]{32}\b/g },
238
+ { type: 'SECRET', regex: /\bhv[sbr]\.[a-zA-Z0-9_-]{24,96}\b/g },
239
+ { type: 'SECRET', regex: /\bdckr_pat_[a-zA-Z0-9_\-]{27,36}\b/g }
222
240
  ],
223
241
  marketing: [
224
242
  { type: 'ID', regex: /\b(?:LEAD|PROSPECT)[-_: ]*[A-Z0-9_-]*[0-9][A-Z0-9_-]*\b/gi },
225
243
  { type: 'ID', regex: /\b(?:CAMPAIGN|CLID|GCLID|FBCLID)[-_:=]*[A-Za-z0-9_-]{10,}\b/gi },
226
- { type: 'FINANCIAL', regex: /(?<=\b(?:LTV|CAC)[\s:]*)(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,.]+\b/gi },
227
- { type: 'ID', regex: /\b(?:SEGMENT|COHORT)[-_: ]*[0-9]{4,8}\b/gi }
244
+ { type: 'FINANCIAL', regex: /(?<=\b(?:LTV|CAC)[\s:]*)(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,.'’]+\b/gi },
245
+ { type: 'ID', regex: /\b(?:SEGMENT|COHORT)[-_: ]*[0-9]{4,8}\b/gi },
246
+ { type: 'ID', regex: /\b(?:G-[A-Z0-9]{8,12}|UA-\d{4,10}-\d{1,4})\b/g },
247
+ { type: 'ID', regex: /\b(?:MARKETO|PARDOT|KLAVIYO|HUBSPOT_CONTACT)[-_ ]*(?:LEAD|ID)?[:\s#-]*[A-Za-z0-9_-]{6,25}\b/gi },
248
+ { type: 'ID', regex: /(?:\?|&)(?:utm_source|utm_medium|utm_campaign|utm_term|utm_content)=([^&\s#"']+)/gi },
249
+ { type: 'ID', regex: /\b(?:_?ga=)?(?:GA\d\.\d\.)?(\d{9,10}\.\d{9,10})\b/g }
228
250
  ],
229
251
  bizops: [
230
- { type: 'ID', regex: /\b(?:DEAL|KPI|METRIC)[-_: ]?[A-Z0-9]{4,}\b/gi },
231
- { type: 'ID', regex: /\b(?:ENTITY|VENDOR|PARTNER)[-_: ]?[0-9]{4,10}\b/gi },
232
- { type: 'FINANCIAL', regex: /\b(?:REVENUE|EBITDA|PROFIT|MARGIN)[\s:_-]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.]+[KM]?\b/gi },
233
- { type: 'SECRET', regex: /\b(?:NDA|M&A|MERGER)[-_: ]?[A-Z0-9]{4,}\b/gi }
252
+ { type: 'ID', regex: /\b(?:DEAL|KPI|METRIC)[-_: ]+[A-Z0-9_-]{4,}\b/gi },
253
+ { type: 'ID', regex: /\b(?:ENTITY|VENDOR|PARTNER)[-_: ]+[A-Z0-9_-]{4,15}\b/gi },
254
+ { type: 'FINANCIAL', regex: /\b(?:REVENUE|EBITDA|PROFIT|MARGIN)[\s:_-]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.'’]+[KM]?\b/gi },
255
+ { type: 'SECRET', regex: /\b(?:NDA|M&A|MERGER)[-_#][A-Za-z0-9_-]{3,}\b/gi },
256
+ { type: 'ID', regex: /\b(?:CAP[- ]TABLE|EQUITY|OPTION|GRANT|SHAREHOLDER)[-_ ]*(?:ID|REF)?[:\s#-]*[A-Z0-9_-]{4,20}\b/gi },
257
+ { type: 'SECRET', regex: /\b(?:VDR|DATAROOM|DEALROOM)[-_ ]*(?:CODE|ID|STAMP|REF)?[:\s#-]*[A-Za-z0-9_-]{6,25}\b/gi },
258
+ { type: 'SECRET', regex: /\b(?:TERM[- ]SHEET|VALUATION|LOI)[-_ ]*(?:REF|ID|CODE)?[:\s#-]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
259
+ { type: 'ID', regex: /\b(?:DUNS|D-U-N-S)(?:\s+(?:Number|No\.?|#))?[:\s#-]*(\d{2}-\d{3}-\d{4}|\d{9})\b/gi },
260
+ { type: 'ID', regex: /\b\d{10}-\d{2}-\d{6}\b/g },
261
+ { type: 'ID', regex: /\b(?:CIK|Central\s+Index\s+Key)[:\s#]*(\d{10})\b/gi },
262
+ { type: 'ID', regex: /\b(?:ES|ISO|NSO|OPT|RSU|CS|PS|SAFE|CN)[-_]\d{1,6}\b/g }
234
263
  ],
235
264
  sales: [
236
- { type: 'ID', regex: /\bOPPORTUNITY[-_: ]?[A-Z0-9]{5,}\b/gi },
265
+ { type: 'ID', regex: /\bOPPORTUNITY[-_: ]*[A-Z0-9_-]{4,}\b/gi },
266
+ { type: 'ID', regex: /\b(?:DOCUSIGN|CONTRACT)[-_: ]?[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}\b/gi },
237
267
  { type: 'ID', regex: /\b(?:DOCUSIGN|CONTRACT)[-_: ]?[0-9A-F]{8,32}\b/gi },
238
- { type: 'FINANCIAL', regex: /\b(?:ARR|MRR|QUOTA)[\s:]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.]+[KM]?\b/gi },
239
- { type: 'ID', regex: /\b(?:SFDC|HUBSPOT)[-_: ]?[0-9A-Z]{15,18}\b/gi }
268
+ { type: 'FINANCIAL', regex: /\b(?:ARR|MRR|QUOTA)[\s:]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.'’]+[KM]?\b/gi },
269
+ { type: 'ID', regex: /\b(?:SFDC|HUBSPOT)[-_: ]?[0-9A-Z]{15,18}\b/gi },
270
+ { type: 'ID', regex: /\b(?:GONG|CHORUS|SALESLOFT|CALL|RECORDING)[-_ ]*(?:CALL|ID|SESSION)?[:\s#-]*[A-Za-z0-9_-]{8,25}\b/gi },
271
+ { type: 'ID', regex: /\b(?:CADENCE|SEQUENCE|CAMPAIGN)[-_ ]*(?:ID|STEP)?[:\s#-]*[A-Za-z0-9_-]{5,20}\b/gi },
272
+ { type: 'ID', regex: /\b(?:ORDER[- ]FORM|MSA|SOW|QUOTE)[-_: ]*(?:REF|ID|#)?[:\s#-]*[A-Z0-9_-]{4,20}\b/gi }
240
273
  ],
241
274
  support: [
242
- { type: 'ID', regex: /\bTICKET[-_:# ]?[A-Z0-9]{5,10}\b/gi },
275
+ { type: 'ID', regex: /\bTICKET[-_:# ]*[-A-Z0-9_]*\d[-A-Z0-9_]*\b/gi },
243
276
  { type: 'ID', regex: /\b(?:ZENDESK|INTERCOM|JIRA)[-_:# ]?[0-9]{4,10}\b/gi },
244
- { type: 'ID', regex: /\b(?:REFUND|RETURN|RMA)[-_:# ]?[A-Z0-9]{6,12}\b/gi },
245
- { type: 'ID', regex: /\b(?:LOYALTY|REWARDS)[-_:# ]?\d{8,12}\b/gi }
277
+ { type: 'ID', regex: /\b(?:REFUND|RETURN|RMA)[-_:# ]*(?:ID|REF|#|NO)?[:\s#-]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
278
+ { type: 'ID', regex: /\b(?:LOYALTY|REWARDS)[-_:# ]?\d{8,12}\b/gi },
279
+ { type: 'ID', regex: /\b(?:INC|CHG|RITM|PRB|REQ|SCTASK|CS|TASK)\d{7,10}\b/gi },
280
+ { type: 'ID', regex: /\b(?:FRESHDESK|HELPSCOUT|CONVERSATION)[-_:# ]*(?:ID|REF)?[:\s#-]*\d{5,12}\b/gi },
281
+ { type: 'ID', regex: /\b(?:CSAT|NPS|SURVEY)[-_ ]*(?:TOKEN|SESSION|ID)?[:\s#-]*[A-Za-z0-9_-]{8,32}\b/gi }
246
282
  ],
247
283
  realestate: [
248
284
  { type: 'ID', regex: /\b(?:MLS|LIS)[- ]?\d{6,10}\b/gi },
249
285
  { type: 'ID', regex: /\bPARCEL[- ]?\d{5,15}\b/gi },
286
+ { type: 'ID', regex: /\b(?:APN|Assessor(?:'s)?\s*Parcel(?:\s*Number)?|Parcel\s*(?:ID|Number|No\.?|#))[:\s#-]*(\d{2,5}[-\s]\d{2,5}[-\s]\d{2,5}(?:[-\s]\d{1,4})?|\d{6,15})\b/gi },
250
287
  { type: 'ID', regex: /\bTENANT[-_]ID[-_][0-9]{4,}\b/gi },
251
- { type: 'FINANCIAL', regex: /\b(?:RENT|LEASE|ESCROW)[\s:]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,]{3,}\b/gi },
252
- { type: 'SECRET', regex: /\b(?:GATE|DOOR|LOBBY)[-_ ](?:CODE|PIN)[\s:]*\d{4,6}\b/gi }
288
+ { type: 'FINANCIAL', regex: /(?<=\b(?:RENT|LEASE|ESCROW)[\s:]+)(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,.'’]{3,}\b/gi },
289
+ { type: 'SECRET', regex: /\b(?:GATE|DOOR|LOBBY)[-_ ](?:CODE|PIN)[\s:]*\d{4,6}\b/gi },
290
+ { type: 'ID', regex: /\b(?:Escrow\s*(?:Number|No\.?|#|Account|File|Order)|Escrow)[:\s#]*([A-Za-z0-9-]{5,18})\b/gi },
291
+ { type: 'ID', regex: /\b(?:Title\s*Policy|Title\s*Order|Title\s*Commitment)\s*(?:#|ID|No\.?)?[:\s#]*([A-Z0-9-]{6,20})\b/gi },
292
+ { type: 'ID', regex: /\b(?:FHA\s*(?:Case\s*(?:No\.?|Number|#)?)?)[:\s#]*(\d{3}-\d{7})\b/gi }
253
293
  ],
254
294
  compliance: [
255
- { type: 'SECRET', regex: /\b(?:GDPR|HIPAA|CCPA|SOC2|ISO27001)[-_: ]?AUDIT[-_: ]?\d{4}\b/gi },
256
- { type: 'SECRET', regex: /\b(?:DPA|POLICY)[-_: ]?[A-Z0-9]{5,15}\b/gi },
257
- { type: 'ID', regex: /\b(?:SAR|DSAR)[-_\/: ]?[A-Z0-9-/]+\b/gi }
295
+ { type: 'SECRET', regex: /\b(?:GDPR|HIPAA|CCPA|SOC2|ISO27001|NIST|SOX)[-_: ]?(?:AUDIT|COMPLIANCE)[-_: ]?(?:Q[1-4][-_ ]?)?\d{4}\b/gi },
296
+ { type: 'SECRET', regex: /\b(?:DPA|POLICY)[-_ ]*(?:ID|NO|#|CODE|REF)?[:\s_-]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
297
+ { type: 'ID', regex: /\b(?:SAR|DSAR)(?:[-_\/: ]+[A-Z0-9/_-]+|[0-9][A-Z0-9/_-]*)\b/gi },
298
+ { type: 'ID', regex: /\b(?:ATU\d{8}|BE\d{10}|BG\d{9,10}|CY\d{8}[A-Z]|CZ\d{8,10}|DE\d{9}|DK\d{8}|EE\d{9}|EL\d{9}|ES[A-Z0-9]\d{7}[A-Z0-9]|FI\d{8}|FR[A-Z0-9]{2}\d{9}|HR\d{11}|HU\d{8}|IE\d{7}[A-W][A-I]?|IT\d{11}|LT\d{9,12}|LU\d{8}|LV\d{11}|MT\d{8}|NL\d{9}B\d{2}|PL\d{10}|PT\d{9}|RO\d{2,10}|SE\d{12}|SI\d{8}|SK\d{10}|GB\d{9}|CHE-\d{3}\.\d{3}\.\d{3}\s?TVA)\b/g },
299
+ { type: 'ID', regex: /\b(?:SCC|STANDARD[- ]CONTRACTUAL[- ]CLAUSES?)[-_: ]*(?:2021\/914|2021[-_]EU|[A-Z0-9_-]{4,20})\b/gi },
300
+ { type: 'ID', regex: /\bBCR[-_ ]*(?:APPROVAL|CODE|ID|REF)?[-_: ]*[A-Z0-9\/-]{4,20}\b/gi },
301
+ { type: 'ID', regex: /\b(?:DPO|DATA[- ]PROTECTION[- ]OFFICER)[-_: ]*(?:REG|ID|NO|REF|FILING)?[:\s#-]*[A-Z0-9_-]{4,20}\b/gi },
302
+ { type: 'ID', regex: /\b(?:ICO\s+(?:Reg(?:istration)?|Ref|No\.?|#)?)[:\s#-]*([Zz][A-Za-z0-9]?\d{6,7})\b/gi },
303
+ { type: 'ID', regex: /\bFR\d{8,10}\b/g },
304
+ { type: 'ID', regex: /\bEDPBI:[A-Z]{2}:OSS:[A-Z]:\d{4}:\d{3,6}\b/g },
305
+ { type: 'ID', regex: /\b(?:AC|AT|AU|CA|CM|CP|IA|IR|MA|MP|PE|PL|PS|RA|SA|SC|SI|SR)-\d{1,2}(?:\(\d{1,2}\))?\b/g }
258
306
  ],
259
307
  ccpa: [
260
- { type: 'ID', regex: /\b(?:DL|DRIVER['’]?S?\s+LICENSE)[:\s#-]*[A-Z0-9]{6,12}\b/gi },
261
- { type: 'LOCATION', regex: /\b-?\d{1,3}\.\d{4,6}[° ]?[NSns],\s*-?\d{1,3}\.\d{4,6}[° ]?[EWew]\b/g },
308
+ { type: 'ID', regex: /\b(?:DL|DRIVER['’]?S?\s+LICENSE(?:\s+DL)?)[:\s#-]*[-A-Z0-9]{6,15}\b/gi },
309
+ { type: 'LOCATION', regex: /\b-?(?:[0-8]?\d(?:\.\d{3,8})?|90(?:\.0{3,8})?)\s*[°\s]*,\s*-?(?:1[0-7]\d(?:\.\d{3,8})?|180(?:\.0{3,8})?|[0-9]?\d(?:\.\d{3,8})?)\s*\b/g },
262
310
  { type: 'ID', regex: /\b(?:CCPA|CPRA)[-_: ]?OPT[-_ ]OUT\b/gi },
263
- { type: 'ID', regex: /\bACCOUNT[ -]?(?:ID|NUM|NUMBER)[:\s]+[A-Z0-9]{6,20}\b/gi }
311
+ { type: 'ID', regex: /\bACCOUNT[ -]?(?:ID|NUM|NUMBER)[:\s]+[-A-Z0-9]{6,25}\b/gi },
312
+ { type: 'ID', regex: /\b(?:CCPA|CPRA)\s*(?:Request|Inquiry|Ticket|SAR)\s*(?:ID|#|Ref)?[:\s#-]*([A-Za-z0-9_-]{6,36})\b/gi },
313
+ { type: 'SECRET', regex: /\b(?:FACE|VOICE|BIO|FP|IRIS)[-_ ]?(?:TEMPLATE|PRINT|VECTOR|HASH|ID)?[:\s#-]*([a-fA-F0-9]{32,64})\b/gi }
264
314
  ],
265
315
  engineering: [
316
+ ...DEVOPS_SECRETS,
266
317
  { type: 'SECRET', regex: /(?<=\b(?:DB|POSTGRES|REDIS|MYSQL|AWS|SECRET|PASSWORD|TOKEN|API|KEY)[A-Z0-9_]*\s*[:=]\s*["']?)[A-Za-z0-9_-]{10,}/gi },
267
318
  { type: 'ID', regex: /\b[a-z0-9._-]+\/[a-z0-9._-]+:[a-z0-9._-]+\b/g },
268
319
  { type: 'ID', regex: /\b[a-fA-F0-9]{40}\b/g },
269
- { type: 'ID', regex: /\b[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.svc\.cluster\.local\b/g }
320
+ { type: 'ID', regex: /\b[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.svc\.cluster\.local\b/g },
321
+ { type: 'ID', regex: /\barn:(?:aws|aws-cn|aws-us-gov):[a-z0-9-]+:[a-z0-9-]*:(?:\d{12})?:[a-zA-Z0-9-_\/.:*]+\b/g },
322
+ { type: 'ID', regex: /\b(?:[a-z0-9]+(?:[._-][a-z0-9]+)*\/)*[a-z0-9._-]+@sha256:[a-f0-9]{64}\b/g }
270
323
  ],
271
324
  agents: [
272
- { type: 'ID', regex: /\b(?:AGENT|VECTOR|EMBEDDING)[-_: ]?(?:ID[-_: ]?)?[A-Z0-9]{8,}\b/gi },
273
- { type: 'ID', regex: /\bTASK[-_: ]?[A-Z0-9]{5,15}\b/gi },
274
- { type: 'SECRET', regex: /\b(?:SYS_PROMPT|SYSTEM_PROMPT|OPENAI_API_KEY)[-_: ]?[A-Za-z0-9_-]{10,}\b/gi }
325
+ { type: 'ID', regex: /\b(?:AGENT|VECTOR|EMBEDDING)[-_: ]*(?:ID[-_: ]*)?[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
326
+ { type: 'ID', regex: /\bTASK[-_: ]?[A-Z0-9_-]{4,15}\b/gi },
327
+ { type: 'SECRET', regex: /\b(?:SYS[-_]PROMPT|SYSTEM[-_]PROMPT|OPENAI[-_]API[-_]KEY)[-_: ]?[A-Za-z0-9_-]{10,}\b/gi },
328
+ { type: 'ID', regex: /\basst_[a-zA-Z0-9]{20,32}\b/g },
329
+ { type: 'ID', regex: /\b(?:thread|run)_[a-zA-Z0-9]{20,32}\b/g },
330
+ { type: 'ID', regex: /\b(?:PINECONE|WEAVIATE|QDRANT|MILVUS|CHROMA)[-_ ]*(?:INDEX|COLLECTION|NAMESPACE)?[:\s#-]*[a-zA-Z0-9_-]{4,30}\b/gi },
331
+ { type: 'ID', regex: /\b(?:vs|vsfb)_[a-zA-Z0-9]{24}\b/g },
332
+ { type: 'ID', regex: /\bfile-[a-zA-Z0-9]{24}\b/g },
333
+ { type: 'ID', regex: /\bftjob-[a-zA-Z0-9]{24}\b/g },
334
+ { type: 'ID', regex: /\bmsgbatch_[a-zA-Z0-9]{24,32}\b/g },
335
+ { type: 'SECRET', regex: /\bhf_[a-zA-Z0-9]{34,40}\b/g }
275
336
  ],
276
337
  academic: [
277
- { type: 'ID', regex: /\b(?:STUDENT|ALUMNI)[-_:# ]?[0-9]{5,10}\b/gi },
278
- { type: 'ID', regex: /\bCOURSE[-_:# ]?[A-Z]{3,4}[ ]?[0-9]{3,4}\b/gi },
279
- { type: 'ID', regex: /\b(?:FERPA|IRB)[-_:# ]?[A-Z0-9]{5,10}\b/gi },
280
- { type: 'ID', regex: /\bGRADE[S]?[\s:][A-DF][+-]?\b/gi }
338
+ { type: 'ID', regex: /\b(?:STUDENT|ALUMNI)[-_:# ]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
339
+ { type: 'ID', regex: /\bCOURSE[-_:# ]?[A-Z]{2,4}[ ]?[0-9]{3,4}\b/gi },
340
+ { type: 'ID', regex: /\b(?:FERPA|IRB)[-_:# ]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
341
+ { type: 'ID', regex: /\bGRADE[S]?[:\s]+[A-DF][+-]?\b/gi },
342
+ { type: 'ID', regex: /\b(?:[1-9]\s?)?[A-Z][0-9]{2}[A-Z]{2}[0-9]{6}(?:-[0-9]{2})?\b/g },
343
+ { type: 'ID', regex: /\bN\d{10}\b/g },
344
+ { type: 'ID', regex: /\b(?:TRANSCRIPT|REGISTRAR|DIPLOMA)[-_ ]*(?:ID|REF|NO)?[:\s#-]*[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*\b/gi },
345
+ { type: 'ID', regex: /\b000[0-9]-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]\b/g },
346
+ { type: 'ID', regex: /\b10\.\d{4,9}\/[-._;()/:A-Za-z0-9]+\b/g },
347
+ { type: 'ID', regex: /\b(?:arXiv:)?(\d{4}\.\d{4,5}(?:v\d+)?)\b/g },
348
+ { type: 'ID', regex: /\bPMID[:\s#]*(\d{4,8})\b/gi },
349
+ { type: 'ID', regex: /\bPMC\d{7,8}\b/g }
281
350
  ],
282
351
  creative: [
283
- { type: 'SECRET', regex: /\b(?:PROJECT|DRAFT|ASSET|SCRIPT|IP)[-_: ]?[0-9]{4,10}\b/gi },
352
+ { type: 'SECRET', regex: /\b(?:PROJECT|DRAFT|ASSET|SCRIPT|IP)[-_: ]+[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
284
353
  { type: 'SECRET', regex: /\b(?:SPOILER|UNRELEASED|EMBARGOED)\b/gi },
285
- { type: 'NAME', regex: /\b(?:GHOSTWRITER|SOURCE)[:\s][A-Z][a-z]+ [A-Z][a-z]+\b/g }
354
+ { type: 'NAME', regex: /\b(?:GHOSTWRITER|SOURCE)[:\s][A-Z][a-z]+ [A-Z][a-z]+\b/g },
355
+ { type: 'ID', regex: /\b(?:WGA|WGAW|WGAE)[-_: ]*(?:REGISTRATION|REG|#)?[:\s#-]*\d{6,10}\b/gi },
356
+ { type: 'ID', regex: /\bISAN\s?[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]\b/gi },
357
+ { type: 'SECRET', regex: /\b(?:TALENT|MODEL|ACTOR|CAST)[-_ ]RELEASE[-_ ]*(?:ID|NO|REF)?[:\s#-]*[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*\b/gi },
358
+ { type: 'ID', regex: /\b(?:ISRC[:\s#]*)?([A-Z]{2}-?[A-Z0-9]{3}-?[0-9]{2}-?[0-9]{5})\b/g },
359
+ { type: 'ID', regex: /\b(?:ISBN(?:-1[03])?[:\s#]*)?(?:97[89][-\s]?)?\d{1,5}[-\s]?\d{1,7}[-\s]?\d{1,6}[-\s]?[0-9X]\b/g },
360
+ { type: 'ID', regex: /\b10\.\d{4,9}\/[-._;()/:A-Za-z0-9]+\b/g },
361
+ { type: 'ID', regex: /\b10\.5240\/(?:[0-9A-Fa-f]{4}-){5}[0-9A-Za-z]\b/g },
362
+ { type: 'ID', regex: /\b(?:SAG(?:-AFTRA)?|AFTRA)\s*(?:ID|#|Member(?:ship)?|No\.?)[:\s#-]*(\d{6,8})\b/gi },
363
+ { type: 'ID', regex: /\b(?:IPI|CAE|ASCAP|BMI|SESAC)\s*(?:Party|Writer|Publisher|Account|ID|#|No\.?)[:\s#-]*(\d{6,11})\b/gi }
286
364
  ],
287
365
  tech: [
288
- { type: 'ID', regex: /\b(?:INSTANCE|NODE|CLUSTER)[-_]ID[-_][a-z0-9-]{10,}\b/gi },
289
- { type: 'ID', regex: /\bENV[-_: ]?(?:PROD|STAGING|DEV|TEST|QA)\b/gi },
290
- { type: 'SECRET', regex: /\b(?:CONFIG|KUBECONFIG|TFSTATE)[-_: ]?[A-Z0-9]{6,15}\b/gi }
366
+ ...DEVOPS_SECRETS,
367
+ { type: 'ID', regex: /\b(?:INSTANCE|NODE|CLUSTER)[-_]ID[-_][a-z0-9-]{5,30}\b/gi },
368
+ { type: 'ID', regex: /\bENV[-_: ]*(?:PROD|STAGING|DEV|TEST|QA)\b/gi },
369
+ { type: 'SECRET', regex: /\b(?:CONFIG|KUBECONFIG|TFSTATE)[-_: ]?[A-Z0-9_-]{4,20}\b/gi },
370
+ { type: 'ID', regex: /\b(?:GCP[- ]PROJECT|PROJECT[- ]ID)[:\s#-]*[a-z][a-z0-9-]{4,28}[a-z0-9]\b/gi },
371
+ { type: 'ID', regex: /\b(?:AZURE[- ](?:SUBSCRIPTION|TENANT)|AZ[- ]SUB)[:\s#-]*[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/gi },
372
+ { type: 'ID', regex: /\b(?:i|sg|vpc|subnet|ami|snap|vol|eni|rtb|nat|igw|vgw|tgw|pcx|eipalloc|acl)-[a-f0-9]{8,17}\b/g },
373
+ { type: 'ID', regex: /\b\/subscriptions\/[0-9a-fA-F-]{36}\/resourceGroups\/[a-zA-Z0-9._-]+\/providers\/[a-zA-Z0-9._-]+\/[a-zA-Z0-9._\/-]+\b/gi }
291
374
  ],
292
375
  personal: [
293
376
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
294
377
  { type: 'SECRET', regex: /\b(?:PASSWORD|PWD|SECRET|PIN)[\s:]*[\S]{4,20}\b/gi },
295
- { type: 'PHONE', regex: /\b(?:WIFE|HUSBAND|PARTNER|MOM|DAD)[\s:]+(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}\b/gi }
378
+ { type: 'PHONE', regex: /\b(?:WIFE|HUSBAND|PARTNER|MOM|DAD)[\s:]+(?:\+?\d{1,3}[\s.-]*)?(?:\(?\d{2,4}\)?[\s.-]*)?[\d\s.-]{7,15}\b/gi },
379
+ { type: 'FINANCIAL', regex: /\b(?:CHECKING|SAVINGS|DEPOSIT)\s*(?:ACCOUNT|ACCT)?[:\s#-]*\d{6,17}\b/gi },
380
+ { type: 'PHONE', regex: /\b(?:SON|DAUGHTER|BROTHER|SISTER|MOTHER|FATHER|CHILD|PARENT)[\s:]+(?:\+?\d{1,3}[\s.-]*)?(?:\(?\d{2,4}\)?[\s.-]*)?[\d\s.-]{7,15}\b/gi },
381
+ { type: 'SECRET', regex: /\b(?:MASTER|DEVICE|BACKUP|SAFE)\s*(?:PIN|PASSCODE|CODE)[\s:]*\d{4,8}\b/gi },
382
+ { type: 'ID', regex: /\b(?:Passport)(?:\s+(?:Number|No\.?|#))?[:\s#]*([A-Z0-9]{8,10})\b/gi },
383
+ { type: 'ID', regex: /\b(?:SkyMiles|AAdvantage|MileagePlus|Rapid\s+Rewards|Frequent\s+Flyer|Marriott|Bonvoy|Hilton\s+Honors|Hyatt|Rewards?|Loyalty)\s*(?:#|No\.?|Number|Account)?[:\s#]*([A-Z0-9-]{7,12})\b/gi }
296
384
  ],
297
385
  wealthmgmt: [
298
386
  { type: 'LEGAL', regex: /\b(?:THE\s+)?[A-Z][A-Z\s.'-]{4,}\s+(?:(?:REVOCABLE|IRREVOCABLE|LIVING|FAMILY|TESTAMENTARY|CHARITABLE|GENERATION-SKIPPING)\s+)*TRUST\b/g },
299
387
  // Mixed-Caps name: All-Caps first name (3+ chars) + optional initials + Mixed-Case last name
300
388
  // Handles PDF-rendered trust names where OCR/extraction produces e.g. "KKKKK I. Mmmmmmm"
301
389
  { type: 'NAME', regex: /(?<=^|[^\p{L}\p{N}_])\p{Lu}{3,}(?:[\p{Lu}'-]*\p{Lu})?(?:[ \t\xA0]+\p{Lu}\.)*[ \t\xA0]+\p{Lu}\p{Ll}[\p{Ll}'-]*(?:\p{Lu}[\p{Ll}'-]*)?\p{L}(?:'s)?(?=[^\p{L}\p{N}_]|$)/gu },
390
+ { type: 'ID', regex: /\b(?:TRUST|ANNUITY|BENEFICIARY)[-_][A-Z0-9_-]{4,20}\b/gi },
391
+ { type: 'ID', regex: /\b(?:LEI|LEGAL[- ]ENTITY[- ]IDENTIFIER)[:\s#-]*[0-9A-Z]{20}\b/gi },
302
392
  { type: 'FINANCIAL', regex: /\b(?:ABA|Routing(?:\s+No)?|RTN)[:\s#]*\d{9}\b/gi },
393
+ { type: 'FINANCIAL', regex: /\bPORTFOLIO[-_][A-Z0-9_-]{5,}\b/gi },
394
+ { type: 'FINANCIAL', regex: /\b(?:Account|Acct\.?|Brokerage|Custodial)\s*(?:Account|Acct)?\s*(?:Number|Num|No\.?|#)?[:\s#]*\d{6,16}\b/gi },
303
395
  { type: 'FINANCIAL', regex: /\b(?:Account|Acct\.?)[:\s#]*\d{4}[-\s]?\d{4}[-\s]?\d{2,6}\b/gi },
304
396
  { type: 'FINANCIAL', regex: /\b(?:Policy|Contract)\s*(?:No\.?|Number|#)[:\s]+[A-Z0-9][A-Z0-9\-]{3,14}\b/gi },
305
397
  { type: 'ID', regex: /\bCRD\s*#?\s*\d{4,8}\b/gi },
306
- { type: 'FINANCIAL', regex: /\b(?:Annual\s+(?:Distribution|Withdrawal)|RMD|Required\s+Minimum\s+Distribution)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.][\d]{2})?\b/gi },
307
- { type: 'FINANCIAL', regex: /\b(?:Portfolio|Market\s+Value|Net\s+Worth|AUM|Total\s+Assets)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.]+[KMB]?\b/gi },
308
- { type: 'FINANCIAL', regex: /\b(?:Roth\s+)?(?:IRA|401k|401\(k\)|403b|403\(b\)|SEP|SIMPLE)\s*(?:Account|Acct|Plan)?\s*(?:No|Number|#)?[:\s#]*[A-Z0-9]{4,15}\b/gi }
398
+ { type: 'FINANCIAL', regex: /\b(?:Annual\s+(?:Distribution|Withdrawal)|RMD|Required\s+Minimum\s+Distribution)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.'’]+\b/gi },
399
+ { type: 'FINANCIAL', regex: /\b(?:Portfolio|Market\s+Value|Net\s+Worth|AUM|Total\s+Assets)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.'’]+[KMB]?\b/gi },
400
+ { type: 'FINANCIAL', regex: /\b(?:Roth\s+)?(?:IRA|401k|401\(k\)|403b|403\(b\)|SEP|SIMPLE)\s*(?:Account|Acct|Plan)?\s*(?:No|Number|#)?[:\s#]*[A-Z0-9]{4,15}\b/gi },
401
+ { type: 'ID', regex: /\bCUSIP[:\s#]*([0-9A-Z]{9})\b/gi },
402
+ { type: 'ID', regex: /\bISIN[:\s#]*([A-Z]{2}[0-9A-Z]{9}[0-9])\b/gi },
403
+ { type: 'ID', regex: /\b(?:Form\s+ADV|SEC)\s*(?:File|No\.?|Number|#)?[:\s#]*(?:801|802)-\d{5,8}\b/gi },
404
+ { type: 'ID', regex: /\bSeries\s+(?:7|63|65|66)\s*(?:License|#|No\.?|Number)?[:\s#]*\d{4,8}\b/gi }
309
405
  ],
310
406
  insurance: [
311
- { type: 'ID', regex: /\b(?:Claim|CLM)[:\s#-]*[A-Z0-9]{6,15}\b/gi },
312
- { type: 'ID', regex: /\b(?:Policy|POL)[:\s#-]*[A-Z]{0,4}[-]?\d{6,12}\b/gi },
313
- { type: 'FINANCIAL', regex: /\b(?:Loss|Claim\s+Amount|Settlement|Reserve|Indemnity)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
314
- { type: 'ID', regex: /\b(?:Adjuster\s+(?:ID|No)|Claim\s+Rep(?:\.|resentative)?)[:\s#]*[A-Z0-9]{4,12}\b/gi },
315
- { type: 'ID', regex: /\bNAIC[:\s#]*\d{5}\b/gi },
316
- { type: 'FINANCIAL', regex: /\b(?:Deductible|Premium|Coverage\s+Amount)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
407
+ { type: 'ID', regex: /\b(?:Claim|CLM)[-_: #]*(?:ID|NO|#|NUM|NUMBER|REF)?[:\s#-]*[-A-Z0-9]*\d[-A-Z0-9]*\b/gi },
408
+ { type: 'ID', regex: /\b(?:Policy|POL)[-_: #]*(?:ID|NO|#|NUM|NUMBER)?[:\s#-]*[-A-Z0-9]*\d[-A-Z0-9]*\b/gi },
409
+ { type: 'FINANCIAL', regex: /\b(?:Loss|Claim\s+Amount|Claim\s+Settlement|Settlement|Reserve|Indemnity)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.'’]+\b/gi },
410
+ { type: 'ID', regex: /\b(?:(?:Assigned\s+)?Adjuster\s+(?:ID|No)|Claim\s+Rep(?:\.|resentative)?)[:\s#]*[-A-Z0-9]{4,15}\b/gi },
411
+ { type: 'ID', regex: /\bNAIC(?:\s+(?:Company\s+)?(?:Code|CoCode|No\.?|Number|#))?[:\s#]*(\d{5})\b/gi },
412
+ { type: 'FINANCIAL', regex: /\b(?:Deductible|Premium|Coverage\s+Amount)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.'']+\b/gi },
317
413
  { type: 'ID', regex: /\b[A-HJ-NPR-Z0-9]{17}\b/g },
318
414
  { type: 'ID', regex: /\b(?:Insured|Named\s+Insured)[:\s]+[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+/g },
319
- { type: 'ID', regex: /\b(?:Agent|Producer)\s*(?:Code|No|ID)[:\s#]*[A-Z0-9]{4,12}\b/gi }
415
+ { type: 'ID', regex: /\b(?:Agent|Producer)\s*(?:Code|No|ID)[:\s#]*[-A-Z0-9]{4,15}\b/gi },
416
+ { type: 'ID', regex: /\b(?:Binder|Certificate(?:\s+of\s+Insurance)?|COI)\s*(?:ID|No\.?|Number|#)?[:\s#-]*([A-Za-z0-9\/-]{4,30})\b/gi },
417
+ { type: 'ID', regex: /\b(?:FCA|FRN|Firm\s*Reference\s*(?:Number|No\.?|#))[:\s#]*(\d{6,7})\b/gi },
418
+ { type: 'ID', regex: /\b(?:Lloyd'?s\s+)?Syndicate\s*(?:No\.?|Number|#)?[:\s#]*(\d{1,4})\b/gi },
419
+ { type: 'ID', regex: /\b(?:AM\s*Best|AMB)\s*(?:#|No\.?|Number|ID)?[:\s#]*(\d{6})\b/gi }
320
420
  ],
321
421
  accounting: [
322
422
  { type: 'ID', regex: /\b(?:EIN|FEIN|Tax\s+ID)[:\s#]*\d{2}-\d{7}\b/gi },
323
- { type: 'FINANCIAL', regex: /\b(?:AGI|Adjusted\s+Gross\s+Income|Taxable\s+Income|Total\s+Income)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
324
- { type: 'FINANCIAL', regex: /\bBox\s+\d{1,2}[a-z]?[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
423
+ { type: 'FINANCIAL', regex: /\b(?:AGI|Adjusted\s+Gross\s+Income|Taxable\s+Income|Total\s+Income)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.'’]+\b/gi },
424
+ { type: 'FINANCIAL', regex: /\b(?:Form\s+|Withheld\s+)?Box\s+\d{1,2}[a-z]?(?:\s*:\s*[A-Z])?\s*[:\s]+(?:[$\u20ac\u00a3\u00a5\u20aa\u20bd\u20b9]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.\u2018\u2019]+\b/gi },
325
425
  { type: 'ID', regex: /\b(?:Form|Schedule)\s+(?:1040|1040-SR|W-2|W-4|1099-[A-Z]{1,4}|K-1|941|990|4562)\b/gi },
326
- { type: 'FINANCIAL', regex: /\b(?:Federal|State)\s+(?:Tax\s+)?(?:Refund|Amount\s+Owed|Balance\s+Due)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
426
+ { type: 'FINANCIAL', regex: /\b(?:Federal|State|Assessed)?\s*(?:Tax\s+Due|Balance\s+Due|Overpayment|Refund)[:\s]+(?:[$\u20ac\u00a3\u00a5\u20aa\u20bd\u20b9]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.\u2018\u2019]+\b/gi },
327
427
  { type: 'ID', regex: /\b(?:State\s+Tax\s+ID|SUI|UI\s+Account\s+No)[:\s#]*[A-Z]{0,3}[-]?\d{4,15}\b/gi },
328
- { type: 'FINANCIAL', regex: /\b(?:Net\s+Pay|Gross\s+Pay|Taxable\s+Wages)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
329
- { type: 'ID', regex: /\b(?:CAF|Practitioner\s+(?:PIN|ID)|PTIN)[:\s#]*[A-Z]?\d{6,9}\b/gi }
428
+ { type: 'FINANCIAL', regex: /\b(?:Gross|Net|Medicare|Social\s+Security)\s+(?:Pay|Wages|Tips|Withholding)[:\s]+(?:[$\u20ac\u00a3\u00a5\u20aa\u20bd\u20b9]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,.\u2018\u2019]+\b/gi },
429
+ { type: 'ID', regex: /\b(?:CAF(?:\s+ID)?|(?:Practitioner|Tax\s+Preparer)\s+(?:PIN|ID)|PTIN)[:\s#]*[A-Z0-9-]{6,12}\b/gi },
430
+ { type: 'ID', regex: /\bEFIN[:\s#]*\d{6}\b/gi },
431
+ { type: 'ID', regex: /\bGL[-_\s]*(?:Account|Acct|Code)?[:\s#]*\d{4,10}\b/gi },
432
+ { type: 'ID', regex: /\b(?:Cost\s+Center|CC)[-_\s]*(?:ID|Code|#)?[:\s#]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi }
330
433
  ],
331
434
  pharma: [
332
- { type: 'ID', regex: /\b(?:Subject|Patient|Participant)\s+(?:ID|No)[:\s#]*[A-Z0-9]{3,12}\b/gi },
435
+ { type: 'ID', regex: /\b(?:Subject|Patient|Participant)\s+(?:ID|No)[:\s#]*[-A-Z0-9]{3,15}\b/gi },
333
436
  { type: 'ID', regex: /\b(?:Protocol|Study)\s*(?:No|Number|ID)[:\s#]*[A-Z0-9][-A-Z0-9]{3,15}\b/gi },
334
437
  { type: 'ID', regex: /\b(?:IND|NDA|BLA|ANDA)\s*(?:No|Number|#)?[:\s]*\d{3,6}\b/gi },
335
- { type: 'ID', regex: /\bIRB[:\s#]*[A-Z0-9]{4,12}\b/gi },
336
- { type: 'ID', regex: /\b(?:Site\s+(?:No|ID)|Investigator\s+Site)[:\s#]*\d{3,6}\b/gi },
337
- { type: 'ID', regex: /\b(?:Batch|Lot|Serial)\s*(?:No[.]?|Number|#)?[:\s#]*[A-Z0-9][A-Z0-9\-]{3,14}\b/gi },
438
+ { type: 'ID', regex: /\bIRB[:\s#]*[-A-Z0-9]{4,15}\b/gi },
439
+ { type: 'ID', regex: /\b(?:(?:Clinical\s+)?Site\s+(?:No|ID)|Investigator\s+Site)[:\s#]*[-A-Z0-9]{3,10}\b/gi },
440
+ { type: 'ID', regex: /\b(?:(?:Manufacturing\s+)?(?:Batch|Lot)|Serial)\s*(?:No[.]?|Number|#)?[:\s#]*[A-Z0-9][A-Z0-9\-]{3,14}\b/gi },
338
441
  { type: 'PHI', regex: /\b(?:Dose|Dosage)[:\s]+\d+(?:\.\d+)?\s*(?:mg|mcg|mL|IU|units?)\b/gi },
339
- { type: 'ID', regex: /\b(?:CRF|eCRF|Case\s+Report\s+Form)\s*(?:No|Page|ID)?[:\s#]*[A-Z0-9]{2,10}\b/gi }
442
+ { type: 'ID', regex: /\b(?:eCRF|CRF|(?:Electronic\s+)?Case\s+Report\s+Form)\s*(?:No|Page|ID)?[:\s#]*[A-Z0-9-]{2,15}\b/gi },
443
+ { type: 'ID', regex: /\bNCT\d{8}\b/gi },
444
+ { type: 'ID', regex: /\b(?:EudraCT|EU\s*CT)?[:\s#]*(20\d{2}-\d{6}-\d{2})\b/gi },
445
+ { type: 'ID', regex: /\b[Kk]\d{6}\b/g },
446
+ { type: 'ID', regex: /\b[Pp]\d{6}(?:\/S\d{3})?\b/g },
447
+ { type: 'ID', regex: /\b(?:USUBJID|SUBJID|STUDYID|SITEID|INVID)[:\s=]+["']?([A-Za-z0-9_-]{3,35})["']?\b/gi },
448
+ { type: 'ID', regex: /\b(?:Randomization|Rand|RND)\s*(?:ID|Code|No\.?|Number|#)?[:\s#-]*([A-Za-z0-9-]{3,15})\b/gi },
449
+ { type: 'ID', regex: /\b(?:Kit|Medication\s*Kit|Bottle|Dispensing)\s*(?:ID|No\.?|Number|#)?[:\s#-]*([A-Za-z0-9-]{3,15})\b/gi },
450
+ { type: 'ID', regex: /\b(?:SAE|AER|ICSR|CIOMS|Safety\s*Report)\s*(?:ID|No\.?|Number|#|Ref)?[:\s#-]*([A-Za-z0-9-]{4,25})\b/gi }
340
451
  ],
341
452
  underwriting: [
342
453
  // Employer Corporate / Business Names
343
- { type: 'NAME', isContextName: true, regex: /\b(?:[A-Z][A-Za-z0-9&.,'-]*[ \t\xA0]+){1,5}(?:Inc\.?|LLC|Corp\.?|Corporation|Ltd\.?|Limited|Co\.?|Company|Group|Holdings|Solutions|Services|Technologies|Logistics|Industries|Capital|Bank|Partners|LLP|PLLC)(?:\s+(?:LLC|Inc\.?|Corp\.?|Ltd\.?|USA|Group))?\b/g },
454
+ { type: 'NAME', isContextName: true, isCorporateName: true, regex: /\b(?:[A-Z][A-Za-z0-9&.,'-]*[ \t\xA0]+){1,5}(?:Inc\.?|LLC|Corp\.?|Corporation|Ltd\.?|Limited|Co\.?|Company|Group|Holdings|Solutions|Services|Technologies|Logistics|Industries|Capital|Bank|Partners|LLP|PLLC)(?:\s+(?:LLC|Inc\.?|Corp\.?|Ltd\.?|USA|Group))?\b/g },
344
455
  { type: 'NAME', isContextName: true, regex: /(?:Employer|Company|Organization|Business)\s*(?:Name)?[\s:#]+([A-Za-z0-9&.,\s'-]{2,40}?)(?=\r?\n|$|\s{3,}|\t|Address|EIN|FEIN|Phone|W-2|Rate|Pay|Wage)/gi },
345
456
 
346
457
  // W-2 & Tax Identifiers
347
- { type: 'ID', regex: /(?:\b(?:Box\s+d\b|d\.\s*(?:Control|#)?|d\s+Control)\s*(?:number|no\.?|#|num)?[:\s#]*|\bControl\s*(?:number|no\.?|#|num)[:\s#]*|\bControl[:#]\s*)([A-Za-z0-9-]{3,30})/gi },
458
+ { type: 'ID', regex: /(?:\b(?:Box\s+d\b|d\.\s*(?:Control|#)?|d\s+Control)\s*(?:Control\s+)?(?:number|no\.?|#|num)?[:\s#]+|\bControl\s*(?:number|no\.?|#|num)?[:\s#]+|\bControl[:#]\s*)([A-Za-z0-9-]{3,30})/gi },
348
459
  { type: 'ID', regex: /\b(?:EIN|FEIN|Tax\s+ID)[:\s#]*\d{2}-\d{7}\b/gi },
349
460
  { type: 'ID', regex: /\b\d{2}-\d{7}\b/g },
350
461
  { type: 'ID', regex: /\b\d{3}-\d{2}-\d{4}\b/g },
@@ -352,7 +463,7 @@ let PROFILE_RULES = {
352
463
 
353
464
  // Employee, Loan & Payroll IDs
354
465
  { type: 'ID', regex: /\b(?:Employee|Emp|EE|Worker|Borrower|Badge|Advisor|Producer|Agent|Applicant|File)\s*(?:#|ID|No\.?|Number)[:\s#]*[A-Z0-9-]{3,20}\b/gi },
355
- { type: 'ID', regex: /\b(?:Pay\s+Group|Cost\s+Center|Dept|Department)[:\s#]*[A-Za-z0-9_-]{2,30}\b/gi },
466
+ { type: 'ID', regex: /\b(?:Pay\s+Group[:#\s]+[A-Za-z0-9_-]{2,30}|(?:Cost\s+Center|Dept|Department)[:#\s]+[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*)\b/gi },
356
467
  { type: 'ID', regex: /\b(?:Loan|Application|Deal|Borrower|File)\s*(?:#|ID|No\.?|Number)[:\s#]*[A-Za-z0-9-]{4,25}\b/gi },
357
468
 
358
469
  // Direct Deposit, Bank Accounts & Routing Numbers (Masked & Unmasked)
@@ -367,7 +478,7 @@ let PROFILE_RULES = {
367
478
 
368
479
  // Addresses & Locations
369
480
  { type: 'ADDRESS', isContextAddress: true, regex: /(?:(?:Borrower(?:'s)?|Co-Borrower(?:'s)?|Employee(?:'s)?|Employer(?:'s)?|Home|Mailing|Property|Physical)\s+address|(?:(?:\bBox\s+f\b|\bf\.\s*|\bf\s+(?=Employee))\s*(?:Employee(?:'s)?\s*)?address))[\s:#]+([A-Za-z0-9#.,\s-]{4,55}?)(?=\r?\n|$|\s{3,}|\t|City|State|ZIP|SSN|EIN|Phone|Box|\d+\b)/gi },
370
- { type: 'ADDRESS', regex: /\b\d{1,6}[ \t\xA0]+(?:[A-Za-z0-9.-]+[ \t\xA0]+){1,4}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Dr|Drive|Way|Ct|Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Hwy|Highway|Cir|Circle|Trl|Trail|Loop|Row|Pike|Box|PO Box|P\.O\.[ \t\xA0]*Box)\b(?:[ \t\xA0]*,?[ \t\xA0]*(?:Apt|Apartment|Suite|Ste|Unit|#|Fl|Floor|Bldg|Building)\.?[ \t\xA0]*[A-Za-z0-9-]+)?/gi },
481
+ { type: 'ADDRESS', regex: /\b\d{1,6}[ \t\xA0]+(?:[A-Za-z0-9.-]+[ \t\xA0]+){1,4}(?:St|Street|Ave|Avenue|Blvd|Boulevard|Rd|Road|Ln|Lane|Dr|Drive|Way|Ct|(?<!District |Supreme |Circuit |Appellate |Bankruptcy |High |Federal |Trial )Court|Pl|Place|Terrace|Pkwy|Parkway|Sq|Square|Hwy|Highway|Cir|Circle|Trl|Trail|Loop|Row|Pike|PO Box|P\.O\.[ \t\xA0]*Box)\b(?:[ \t\xA0]*,?[ \t\xA0]*(?:Apt|Apartment|Suite|Ste|Unit|#|Fl|Floor|Bldg|Building)\.?[ \t\xA0]*[A-Za-z0-9-]+)?/gi },
371
482
  { type: 'ADDRESS', regex: /\b[A-Za-z][a-zA-Z\s.-]{1,25},?\s+(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)\s+\d{5}(?:-\d{4})?\b/g },
372
483
  { type: 'ADDRESS', regex: /\b\d{5}-\d{4}\b/g },
373
484
  { type: 'LOCATION', regex: /\b[A-Za-z][a-zA-Z .'-]{1,25}(?:,\s*(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR)|\s+(?:AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY|DC|PR))\b/g }
@@ -418,8 +529,7 @@ let NAME_STOP_LIST = new Set([
418
529
  'step 1', 'step 2', 'step 3', 'step 4', 'step 5',
419
530
  'page 1', 'page 2', 'page 3', 'page 4', 'page 5',
420
531
  'cs101', 'course cs101',
421
- // Expanded Stop List (Common nouns, command phrases, legal, prompt, chess, and animation terms)
422
- 'docket number', 'docket numbers', 'dockets section', 'case name', 'case names', 'case number', 'case numbers', 'law firm', 'law firms', 'counsel stack', 'counselstack', 'counselstack connector', 'tier 0', 'tier 1', 'tier 2', 'tier 3', 'tier 4', 'do not', 'do not write', 'specific permission', 'write again', 'without permission', 'without specific permission', 'on screen', 'in report', 'own line', 'connector access', 'prompt instruction', 'prompt instructions', 'finding report', 'findings report',
532
+ 'docket number', 'docket numbers', 'dockets section', 'case name', 'case names', 'case number', 'case numbers', 'law firm', 'law firms', 'counsel stack', 'counselstack', 'counselstack connector', 'tier 0', 'tier 1', 'tier 2', 'tier 3', 'tier 4', 'do not', 'do not write', 'specific permission', 'write again', 'without permission', 'without specific permission', 'on screen', 'in report', 'own line', 'connector access', 'prompt instruction', 'prompt instructions', 'finding report', 'findings report', 'wage and tax statement', 'form w-2', 'wage and tax', 'tax statement', 'u.s. individual', 'income tax return', 'earnings statement', 'adp totalsource', 'paychex flex', 'clinical progress note', 'inpatient discharge summary', 'mri brain', 'closing disclosure', 'settlement statement', 'clinical protocol', 'research strategy', 'deposit in escrow', 'incident record', 'institutional review board', 'review board', 'national institutes', 'institutes health', 'dana-farber', 'cancer institute', 'harvard medical school', 'medical school', 'department homeland security', 'homeland security', 'control sc-28', 'sc-28 attestation', 'system security plan', 'morgan stanley', 'blackstone capital', 'communicating pi', 'contractual clauses', 'standard contractual clauses', 'driver license', 'drivers license', 'improvement plan', 'performance improvement plan', 'vehicle identification', 'custodial portfolio', 'brokerage acct', 'brokerage account', 'settlement agreement', 'retainer agreement', 'service level agreement', 'master services agreement', 'order form', 'statement of work', 'data processing addendum', 'binding corporate rules', 'commercial register', 'board resolution', 'power of attorney', 'letters testamentary', 'letters of administration', 'court docket', 'state bar', 'incident report', 'threat actor', 'mitre att&ck', 'sigma rule', 'security information', 'virtual data room', 'cap table', 'term sheet', 'confidential disclosure',
423
533
  'white bishop', 'black bishop', 'white knight', 'black knight', 'white king', 'black king', 'white queen', 'black queen', 'white rook', 'black rook', 'white pawn', 'black pawn', 'chess piece', 'chess pieces', 'chess game', 'chess match', 'disney-pixar', 'disney pixar', 'pixar animation', 'close-up', 'close up',
424
534
  'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december',
425
535
  'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday',
@@ -458,11 +568,27 @@ let NAME_STOP_LIST = new Set([
458
568
  'lighting', 'keyboard', 'creating', 'building', 'training', 'planning', 'starting', 'painting', 'printing', 'returned', 'released', 'required', 'accepted', 'imported', 'services', 'products', 'accounts', 'settings', 'partners', 'keywords', 'keystone', 'keyspace', 'keynotes', 'keychain'
459
569
  , 'quarterly results', 'strategic planning', 'market research', 'customer base', 'privacy settings', 'account settings', 'security settings', 'download now', 'free trial', 'limited time', 'copyright protected', 'all rights', 'rights reserved', 'credit score', 'monthly rent', 'lease application', 'property address', 'reference number', 'additional identifier', 'lease agreement', 'hiring review', 'candidate name', 'privacy policy', 'terms of service', 'machine learning', 'artificial intelligence', 'generative ai', 'silicon valley', 'google cloud', 'amazon web', 'data science', 'operating system', 'software engineer', 'product manager', 'project manager', 'data analyst', 'gross margin', 'revenue growth', 'source code', 'version control', 'large language model',
460
570
  'wages', 'wage', 'tips', 'compensation', 'withheld', 'withholding', 'medicare', 'deductions', 'deduction',
461
- 'regular', 'hours', 'holiday', 'overtime', 'commission', 'bonus', 'bonuses', 'records', 'record', 'statement', 'statements', 'rate', 'rates', 'current', 'ytd', 'benefits', 'taxable', 'pre-tax', 'post-tax', 'reimbursements', 'reimbursement', 'fica', 'oasdi', 'disability', 'unemployment', 'sui', 'sdi', 'std', 'ltd', 'exemptions', 'exemption', 'allowances', 'allowance', 'filing', 'status', 'single', 'married', 'head', 'household', 'advice', 'frequency', 'bi-weekly', 'biweekly', 'weekly', 'monthly', 'semi-monthly', 'direct', 'deposit', 'routing', 'box', 'boxes', 'code', 'control', 'omb', 'copy', 'instructions', 'information', 'deferred', 'adoption', 'statutory', 'third-party', 'sick', 'form', 'schedule', 'w-2', 'w2', 'w-4', 'w4', '1099', 'k-1', '1040', 'fed', 'med', 'fwt', 'swt', 'fed w/h', 'fed med', 'locality', 'state wages', 'state tax', 'local wages', 'local tax', 'allocated', 'nonqualified', 'suff', 'suffix', 'allocated tips', 'advance eic', 'advance eic payment', 'dependent care', 'dependent care benefits', 'nonqualified plans', 'statutory employee', 'retirement plan', 'third-party sick pay']);
571
+ 'regular', 'hours', 'holiday', 'overtime', 'commission', 'bonus', 'bonuses', 'records', 'record', 'statement', 'statements', 'rate', 'rates', 'current', 'ytd', 'benefits', 'taxable', 'pre-tax', 'post-tax', 'reimbursements', 'reimbursement', 'fica', 'oasdi', 'disability', 'unemployment', 'sui', 'sdi', 'std', 'ltd', 'exemptions', 'exemption', 'allowances', 'allowance', 'filing', 'status', 'single', 'married', 'head', 'household', 'advice', 'frequency', 'bi-weekly', 'biweekly', 'weekly', 'monthly', 'semi-monthly', 'direct', 'deposit', 'routing', 'box', 'boxes', 'code', 'control', 'omb', 'copy', 'instructions', 'information', 'deferred', 'adoption', 'statutory', 'third-party', 'sick', 'form', 'schedule', 'w-2', 'w2', 'w-4', 'w4', '1099', 'k-1', '1040', 'fed', 'med', 'fwt', 'swt', 'fed w/h', 'fed med', 'locality', 'state wages', 'state tax', 'local wages', 'local tax', 'allocated', 'nonqualified', 'suff', 'suffix', 'allocated tips', 'advance eic', 'advance eic payment', 'dependent care', 'dependent care benefits', 'nonqualified plans', 'statutory employee', 'retirement plan', 'third-party sick pay',
572
+ 'uk', 'eu', 'us', 'usa', 'dpa', 'ico', 'dpo', 'ciso', 'ssrn', 'elsevier', 'gdpr', 'ccpa', 'cpra', 'hipaa', 'soc2', 'iso27001', 'governance', 'regulatory', 'framework', 'mandate', 'mandates', 'guidance', 'statute', 'statutes', 'jurisdiction', 'jurisdictions', 'recital', 'article', 'articles', 'treatise', 'workstation', 'device', 'endpoint', 'blueprint', 'personal', 'cross-border', 'cross', 'border', 'transfer', 'retrieval', 'augmented', 'generation', 'limitation', 'discrimination', 'imposes', 'heavy', 'identifiable', 'bypasses', 'author', 'authors', 'contact', 'contacts', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint', 'abstract', 'structured', 'background', 'methods', 'results', 'discussion', 'conclusion', 'conclusions', 'introduction', 'overview', 'workflow', 'paradigm', 'nomenclature', 'repository', 'classification', 'phenotypes', 'biomedical', 'bioinformatics', 'identifiers', 'de-identification', 'sanitization', 'ephemeral', 'validation', 'validating', 'genomic', 'genomics', 'clinical', 'phenotype', 'target', 'corresponding', 'subject', 'biorxiv', 'medrxiv', 'arxiv', 'privacyscrubber', 'research', 'lead', 'architect', 'chief', 'founder', 'symbols', 'gene', 'genes', 'sample', 'barcode', 'pipeline', 'downstream', 'pedigree', 'trees', 'exposes', 'violates', 'protecting', 'anonymization', 'redacted', 'redaction', 'zero-trust', 'ztds',
573
+ 'conventional', 'model', 'models', 'potential', 'multi', 'million', 'dollar', 'dollars', 'surrogate', 'surrogates', 'geographic', 'subdivisions', 'subdivision', 'inference', 'response', 'responses', 'latency', 'benchmarks', 'benchmark', 'experimental', 'methodology', 'informatics', 'ethics', 'accountability', 'civil', 'rights', 'perimeter', 'network', 'requirements', 'requirement', 'statutory', 'categories', 'category', 'regulations', 'regulation', 'penalties', 'penalty', 'disclosure', 'disclosures', 'clinician', 'terminal', 'transport', 'inpatient', 'discharge', 'summaries', 'operative', 'reports', 'outpatient', 'psychiatric', 'telehealth', 'consultation', 'pathology', 'sequencing', 'laboratory', 'sensitivity', 'specificity', 'proxy', 'gateways', 'gateway', 'packet', 'packets', 'inspection', 'declarations', 'availability', 'competing', 'interests', 'interventions', 'multicenter', 'multi-center', 'institution', 'institutional', 'protocol', 'deviations', 'adverse', 'events', 'abbreviations', 'agents', 'agent', 'committee', 'committees', 'board', 'boards', 'nih', 'pubmed', 'central', 'open', 'access', 'policy', 'trial', 'trials', 'crf', 'crfs', 'ehr', 'ehrs', 'baa', 'baas', 'hitech', 'safe', 'harbor', 'section']);
462
574
 
463
- let JARGON_WORDS = new Set(['step', 'page', 'grade', 'version', 'course', 'class', 'follow', 'chapter', 'lesson', 'unit', 'marketing', 'manager', 'specialist', 'science', 'administration', 'university', 'skills', 'leadership', 'communication', 'working', 'proficiency', 'decision', 'driven', 'experience', 'summary', 'bachelor', 'ads', 'solutions', 'positioning', 'acquisition', 'strategy', 'research', 'database', 'forecast', 'interest', 'prepared', 'merchant', 'document', 'feedback', 'template', 'campaign', 'partners', 'settings', 'keystone', 'llm', 'gpt', 'chatgpt', 'openai', 'anthropic', 'claude', 'gemini', 'api', 'json', 'xml', 'html', 'css', 'javascript', 'python', 'golang', 'typescript', 'rust', 'fastapi', 'snowflake', 'kubernetes', 'terraform', 'docker', 'redis', 'kafka', 'pytorch', 'policy', 'terms', 'conditions', 'release', 'sprint', 'deployment', 'cluster', 'instance', 'package', 'module', 'revenue', 'margin', 'gross', 'quarter', 'system', 'code', 'data', 'cloud', 'server', 'database', 'artificial', 'intelligence', 'learning', 'generative', 'regular', 'hours', 'holiday', 'earnings', 'deductions', 'withheld', 'withholding', 'taxes', 'medicare', 'benefits', 'reimbursements', 'compensation', 'wages', 'code']);
575
+ let JARGON_WORDS = new Set(['step', 'page', 'grade', 'version', 'course', 'class', 'follow', 'chapter', 'lesson', 'unit', 'marketing', 'manager', 'specialist', 'science', 'administration', 'university', 'skills', 'leadership', 'communication', 'working', 'proficiency', 'decision', 'driven', 'experience', 'summary', 'bachelor', 'ads', 'solutions', 'positioning', 'acquisition', 'strategy', 'research', 'database', 'forecast', 'interest', 'prepared', 'merchant', 'document', 'feedback', 'template', 'campaign', 'partners', 'settings', 'keystone', 'llm', 'gpt', 'chatgpt', 'openai', 'anthropic', 'claude', 'gemini', 'api', 'json', 'xml', 'html', 'css', 'javascript', 'python', 'golang', 'typescript', 'rust', 'fastapi', 'snowflake', 'kubernetes', 'terraform', 'docker', 'redis', 'kafka', 'pytorch', 'policy', 'terms', 'conditions', 'release', 'sprint', 'deployment', 'cluster', 'instance', 'package', 'module', 'revenue', 'margin', 'gross', 'quarter', 'system', 'code', 'data', 'cloud', 'server', 'database', 'artificial', 'intelligence', 'learning', 'generative', 'regular', 'hours', 'holiday', 'earnings', 'deductions', 'withheld', 'withholding', 'taxes', 'medicare', 'benefits', 'reimbursements', 'compensation', 'wages', 'code', 'uk', 'eu', 'us', 'usa', 'dpa', 'ico', 'dpo', 'ciso', 'ssrn', 'elsevier', 'gdpr', 'ccpa', 'cpra', 'hipaa', 'soc2', 'iso27001', 'governance', 'regulatory', 'framework', 'mandate', 'mandates', 'guidance', 'statute', 'statutes', 'jurisdiction', 'jurisdictions', 'recital', 'article', 'articles', 'treatise', 'workstation', 'device', 'endpoint', 'blueprint', 'personal', 'cross-border', 'cross', 'border', 'transfer', 'retrieval', 'augmented', 'generation', 'limitation', 'discrimination', 'imposes', 'heavy', 'identifiable', 'bypasses', 'author', 'authors', 'contact', 'contacts', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint', 'abstract', 'structured', 'background', 'methods', 'results', 'discussion', 'conclusion', 'conclusions', 'introduction', 'overview', 'workflow', 'paradigm', 'nomenclature', 'repository', 'classification', 'phenotypes', 'biomedical', 'bioinformatics', 'identifiers', 'de-identification', 'sanitization', 'ephemeral', 'validation', 'validating', 'genomic', 'genomics', 'clinical', 'phenotype', 'target', 'corresponding', 'subject', 'biorxiv', 'medrxiv', 'arxiv', 'privacyscrubber', 'research', 'lead', 'architect', 'chief', 'founder', 'symbols', 'gene', 'genes', 'sample', 'barcode', 'pipeline', 'downstream', 'pedigree', 'trees', 'exposes', 'violates', 'protecting', 'anonymization', 'redacted', 'redaction', 'zero-trust', 'ztds',
576
+ 'conventional', 'model', 'models', 'potential', 'multi', 'million', 'dollar', 'dollars', 'surrogate', 'surrogates', 'geographic', 'subdivisions', 'subdivision', 'inference', 'response', 'responses', 'latency', 'benchmarks', 'benchmark', 'experimental', 'methodology', 'informatics', 'ethics', 'accountability', 'civil', 'rights', 'perimeter', 'network', 'requirements', 'requirement', 'statutory', 'categories', 'category', 'regulations', 'regulation', 'penalties', 'penalty', 'disclosure', 'disclosures', 'clinician', 'terminal', 'transport', 'inpatient', 'discharge', 'summaries', 'operative', 'reports', 'outpatient', 'psychiatric', 'telehealth', 'consultation', 'pathology', 'sequencing', 'laboratory', 'sensitivity', 'specificity', 'proxy', 'gateways', 'gateway', 'packet', 'packets', 'inspection', 'declarations', 'availability', 'competing', 'interests', 'interventions', 'multicenter', 'multi-center', 'institution', 'institutional', 'protocol', 'deviations', 'adverse', 'events', 'abbreviations', 'agents', 'agent', 'committee', 'committees', 'board', 'boards', 'nih', 'pubmed', 'central', 'open', 'access', 'policy', 'trial', 'trials', 'crf', 'crfs', 'ehr', 'ehrs', 'baa', 'baas', 'hitech', 'safe', 'harbor', 'section']);
577
+
578
+ const US_STATES_SET = new Set([
579
+ 'california', 'texas', 'florida', 'york', 'illinois', 'pennsylvania', 'ohio', 'georgia', 'michigan', 'carolina', 'virginia', 'washington', 'arizona', 'massachusetts', 'tennessee', 'indiana', 'maryland', 'missouri', 'wisconsin', 'colorado', 'minnesota', 'alabama', 'louisiana', 'kentucky', 'oregon', 'oklahoma', 'connecticut', 'utah', 'iowa', 'nevada', 'arkansas', 'mississippi', 'kansas', 'new mexico', 'nebraska', 'idaho', 'hawaii', 'maine', 'new hampshire', 'rhode island', 'montana', 'delaware', 'south dakota', 'north dakota', 'alaska', 'vermont', 'wyoming'
580
+ ]);
581
+
582
+ const CORPORATE_SUFFIXES = new Set([
583
+ 'inc', 'llc', 'corp', 'corporation', 'ltd', 'limited', 'co', 'company',
584
+ 'group', 'holdings', 'solutions', 'services', 'technologies', 'logistics',
585
+ 'industries', 'capital', 'bank', 'partners', 'llp', 'pllc', 'usa'
586
+ ]);
464
587
 
465
588
  let NOT_NAME_WORDS = new Set([
589
+ 'uk', 'eu', 'us', 'usa', 'dpa', 'ico', 'dpo', 'ciso', 'ssrn', 'elsevier', 'gdpr', 'ccpa', 'cpra', 'hipaa', 'soc2', 'iso27001', 'governance', 'regulatory', 'framework', 'mandate', 'mandates', 'guidance', 'statute', 'statutes', 'jurisdiction', 'jurisdictions', 'recital', 'article', 'articles', 'treatise', 'workstation', 'device', 'endpoint', 'blueprint', 'personal', 'cross-border', 'cross', 'border', 'transfer', 'retrieval', 'augmented', 'generation', 'limitation', 'discrimination', 'imposes', 'heavy', 'identifiable', 'bypasses', 'author', 'authors', 'contact', 'contacts', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint', 'abstract', 'structured', 'background', 'methods', 'results', 'discussion', 'conclusion', 'conclusions', 'introduction', 'overview', 'workflow', 'paradigm', 'nomenclature', 'repository', 'classification', 'phenotypes', 'biomedical', 'bioinformatics', 'identifiers', 'de-identification', 'sanitization', 'ephemeral', 'validation', 'validating', 'genomic', 'genomics', 'clinical', 'phenotype', 'target', 'corresponding', 'subject', 'biorxiv', 'medrxiv', 'arxiv', 'privacyscrubber', 'research', 'lead', 'architect', 'chief', 'founder', 'symbols', 'gene', 'genes', 'sample', 'barcode', 'pipeline', 'downstream', 'pedigree', 'trees', 'exposes', 'violates', 'protecting', 'anonymization', 'redacted', 'redaction', 'zero-trust', 'ztds',
590
+ 'conventional', 'model', 'models', 'potential', 'multi', 'million', 'dollar', 'dollars', 'surrogate', 'surrogates', 'geographic', 'subdivisions', 'subdivision', 'inference', 'response', 'responses', 'latency', 'benchmarks', 'benchmark', 'experimental', 'methodology', 'informatics', 'ethics', 'accountability', 'civil', 'rights', 'perimeter', 'network', 'requirements', 'requirement', 'statutory', 'categories', 'category', 'regulations', 'regulation', 'penalties', 'penalty', 'disclosure', 'disclosures', 'clinician', 'terminal', 'transport', 'inpatient', 'discharge', 'summaries', 'operative', 'reports', 'outpatient', 'psychiatric', 'telehealth', 'consultation', 'pathology', 'sequencing', 'laboratory', 'sensitivity', 'specificity', 'proxy', 'gateways', 'gateway', 'packet', 'packets', 'inspection', 'declarations', 'availability', 'competing', 'interests', 'interventions', 'multicenter', 'multi-center', 'institution', 'institutional', 'protocol', 'deviations', 'adverse', 'events', 'abbreviations', 'agents', 'agent', 'committee', 'committees', 'board', 'boards', 'nih', 'pubmed', 'central', 'open', 'access', 'policy', 'trial', 'trials', 'crf', 'crfs', 'ehr', 'ehrs', 'baa', 'baas', 'hitech', 'safe', 'harbor', 'section',
591
+ 'retirement', 'roth', 'ira', 'acct', 'custodial', 'brokerage', 'portfolio', 'annuity', 'dividend', 'distribution', 'reconciliation', 'withholding', 'remuneration', 'pin', 'lobby', 'passcode', 'code', 'gate', 'door', 'access', 'tenant', 'landlord', 'escrow', 'cadastral', 'claim', 'claims', 'adjuster', 'insured', 'carrier', 'indemnity', 'underwriter', 'underwriting', 'deductible', 'premium', 'settlement', 'loss', 'cargo', 'writers', 'guild', 'ghostwriter', 'actor', 'screenplay', 'audiovisual', 'cinematic', 'co-production', 'alumnus', 'alumni', 'registrar', 'transcript', 'diploma', 'orchestration', 'runtime', 'helpdesk', 'freshdesk', 'intercom', 'zendesk', 'investigational', 'pharmacovigilance', 'reaction', 'medication', 'manufacturing', 'lot', 'industrial', 'electronics', 'driver', 'drivers', 'license', 'licence', 'clearing', 'house', 'automated', 'central', 'securities', 'depository', 'arbitration', 'tribunal', 'instrument', 'infrastructure', 'talent', 'dossier',
466
592
  // Grammatical & Sentence Starters
467
593
  'the', 'a', 'an', 'this', 'that', 'these', 'those', 'my', 'your', 'his', 'her', 'their', 'our', 'its', 'it', 'he', 'she', 'they', 'we', 'i', 'you', 'who', 'whom', 'which', 'what', 'whose', 'why', 'how', 'when', 'where', 'with', 'for', 'from', 'by', 'to', 'at', 'in', 'on', 'of', 'about', 'as', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'and', 'but', 'or', 'so', 'yet', 'im', "i'm", "you're", "they're", "we're", "it's", "he's", "she's", "that's", "there's", "what's", "who's", "i've", "you've", "we've", "they've", "i'll", "you'll", "we'll", "they'll", "i'd", "you'd", "we'd", "they'd",
468
594
  // Verbs, Auxiliaries, Commands & Imperatives
@@ -566,6 +692,7 @@ let NOT_NAME_WORDS = new Set([
566
692
 
567
693
  // General Academic & Professional vocabulary
568
694
  'bachelor', 'master', 'doctor', 'associate', 'degree', 'university', 'college', 'school', 'institute', 'academy', 'graduated', 'major', 'minor', 'gpa', 'cum', 'laude', 'honors', 'deans', 'list', 'scholarship',
695
+ 'language', 'model', 'models', 'llm', 'llms', 'genetic', 'genetics', 'special', 'category', 'categories', 'variant', 'variants', 'allele', 'alleles', 'frequency', 'frequencies', 'chromosome', 'chromosomes', 'mutation', 'mutations', 'phenotype', 'phenotypes', 'expression', 'annotation', 'annotations', 'genomic', 'genomics', 'molecular', 'sequence', 'sequencing', 'reference', 'dataset', 'datasets',
569
696
  // Quality & Adjectives
570
697
  'results', 'driven', 'oriented', 'expert', 'professional', 'proven', 'track', 'record', 'creative', 'excellent', 'communication', 'verbal', 'written', 'native', 'fluent', 'bilingual', 'working', 'proficiency', 'strategic', 'interpersonal', 'teamwork', 'organizational', 'detail', 'analytical',
571
698
  // Common Resume / Business Phrases
@@ -576,8 +703,7 @@ let NOT_NAME_WORDS = new Set([
576
703
  'clinical', 'note', 'notes', 'dx', 'rx', 'tx', 'hx', 'px', 'sx', 'type', 'diabetes', 'referred', 'referral', 'diagnosed', 'diagnosis', 'patient', 'insurance', 'bcbs', 'mrn', 'dob',
577
704
  // Tax & Payroll terms
578
705
  'wages', 'wage', 'tips', 'compensation', 'withheld', 'withholding', 'medicare', 'deductions', 'deduction', 'earning', 'earnings', 'gross', 'net', 'pay', 'payroll', 'paystub', 'taxable', 'exempt', 'allowance', 'allowances', 'regular', 'hours', 'holiday', 'overtime', 'commission', 'bonus', 'bonuses', 'records', 'record', 'statement', 'statements', 'rate', 'rates', 'current', 'ytd', 'benefits', 'taxable', 'pre-tax', 'post-tax', 'reimbursements', 'reimbursement', 'fica', 'oasdi', 'disability', 'unemployment', 'sui', 'sdi', 'std', 'ltd', 'exemptions', 'exemption', 'allowances', 'allowance', 'filing', 'status', 'single', 'married', 'head', 'household', 'advice', 'frequency', 'bi-weekly', 'biweekly', 'weekly', 'monthly', 'semi-monthly', 'direct', 'deposit', 'routing', 'box', 'boxes', 'code', 'control', 'omb', 'copy', 'instructions', 'information', 'deferred', 'adoption', 'statutory', 'third-party', 'sick', 'form', 'schedule', 'w-2', 'w2', 'w-4', 'w4', '1099', 'k-1', '1040', 'fed', 'med', 'fwt', 'swt', 'fed w/h', 'fed med', 'locality', 'state wages', 'state tax', 'local wages', 'local tax', 'allocated', 'nonqualified',
579
- // Common Web, UI, Compliance, Document & AI Terms (Suppresses false-positive Name detection on headlines, buttons, and badges)
580
- 'incident', 'incidents', 'critical', 'production', 'impacted', 'reported', 'details', 'vulnerability', 'vulnerabilities', 'host', 'types', 'type', 'leaked', 'leak', 'leaks', 'masked', 'mask', 'masking', 'leave', 'screen', 'screens', 'risk', 'risks', 'cluster', 'clusters', 'parameter', 'parameters', 'processing', 'process', 'processed', 'verified', 'verify', 'verification', 'playground', 'guide', 'guides', 'protection', 'protect', 'corporate', 'enterprise', 'log', 'logs', 'airplane', 'mode', 'zero', 'trust', 'top', 'data', 'live', 'scrubber', 'scrub', 'scrubbed', 'note', 'notes', 'secret', 'secrets', 'card', 'cards', 'raw', 'input', 'output', 'contains', 'contain', 'contained', 'platform', 'solutions', 'pricing', 'company', 'news', 'dashboard', 'add', 'chrome', 'sample', 'samples', 'try', 'terms', 'privacy', 'policy', 'policies', 'home', 'compliance', 'framework', 'frameworks', 'audit', 'audits', 'receipt', 'receipts', 'overview', 'explore', 'vectors', 'vector', 'standard', 'standards', 'status', 'preview', 'view', 'actions', 'action', 'button', 'buttons', 'option', 'options', 'general', 'specialized', 'custom', 'rule', 'rules', 'token', 'tokens', 'value', 'values', 'session', 'sessions', 'local', 'server', 'servers', 'cloud', 'ram', 'memory', 'offline', 'online', 'client', 'browser', 'extension', 'workspace', 'workplace', 'pan', 'phi', 'pii', 'soc', 'soc2', 'gdpr', 'hipaa', 'ccpa', 'iso27001', 'pci', 'dss', 'nist', 'chatgpt', 'claude', 'gemini', 'copilot', 'perplexity', 'deepseek', 'qwen', 'grok', 'llama', 'mistral', 'ai', 'llm', 'prompt', 'prompts', 'transmission', 'transit', 'egress', 'neutralized', 'stripped', 'isolated', 'isolation', 'unlocked', 'locked', 'unlock', 'download', 'copy', 'dismiss', 'close', 'save', 'settings', 'protect', 'reveal', 'unmask', 'restore', 'restored', 'export', 'import',
706
+ 'incident', 'incidents', 'critical', 'production', 'impacted', 'reported', 'details', 'vulnerability', 'vulnerabilities', 'host', 'types', 'type', 'leaked', 'leak', 'leaks', 'masked', 'mask', 'masking', 'leave', 'screen', 'screens', 'risk', 'risks', 'cluster', 'clusters', 'parameter', 'parameters', 'processing', 'process', 'processed', 'verified', 'verify', 'verification', 'playground', 'guide', 'guides', 'protection', 'protect', 'corporate', 'enterprise', 'log', 'logs', 'airplane', 'mode', 'zero', 'trust', 'top', 'data', 'live', 'scrubber', 'scrub', 'scrubbed', 'note', 'notes', 'secret', 'secrets', 'card', 'cards', 'raw', 'input', 'output', 'contains', 'contain', 'contained', 'platform', 'solutions', 'pricing', 'company', 'news', 'dashboard', 'add', 'chrome', 'sample', 'samples', 'try', 'terms', 'privacy', 'policy', 'policies', 'home', 'compliance', 'framework', 'frameworks', 'audit', 'audits', 'receipt', 'receipts', 'overview', 'explore', 'vectors', 'vector', 'standard', 'standards', 'status', 'preview', 'view', 'actions', 'action', 'button', 'buttons', 'option', 'options', 'general', 'specialized', 'custom', 'rule', 'rules', 'token', 'tokens', 'value', 'values', 'session', 'sessions', 'local', 'server', 'servers', 'cloud', 'ram', 'memory', 'offline', 'online', 'client', 'browser', 'extension', 'workspace', 'workplace', 'pan', 'phi', 'pii', 'soc', 'soc2', 'gdpr', 'hipaa', 'ccpa', 'iso27001', 'pci', 'dss', 'nist', 'chatgpt', 'claude', 'gemini', 'copilot', 'perplexity', 'deepseek', 'qwen', 'grok', 'llama', 'mistral', 'ai', 'llm', 'prompt', 'prompts', 'transmission', 'transit', 'egress', 'neutralized', 'stripped', 'isolated', 'isolation', 'unlocked', 'locked', 'unlock', 'download', 'copy', 'dismiss', 'close', 'save', 'settings', 'protect', 'reveal', 'unmask', 'restore', 'restored', 'export', 'import', 'sanitization', 'sanitizer', 'sensitive', 'entities', 'entity', 'breakdown', 'metrics', 'exposure', 'high', 'low', 'medium', 'cryptographic', 'separation', 'pseudonymization', 'minimization', 'transparency', 'forensic', 'extraction', 'conduit', 'liability', 'processor', 'binding', 'bindings', 'signature', 'certified', 'certificate', 'payload', 'transmitted', 'evaluation', 'air-gapped', 'client-side', 'zero-trust', 'iso', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x', 'statutory', 'declaration', 'pass', 'passed', 'fail', 'failed', 'side', 'privacyscrubber', 'ztds', 'safe harbor', 'harbor', 'safe', 'ciso', 'united', 'states', 'district', 'court', 'northern', 'southern', 'eastern', 'western', 'division', 'in re', 'litigation', 'complaint', 'violation', 'defend', 'trade', 'secrets', 'demand', 'jury', 'trial', 'federal', 'question', 'diversity', 'citizenship', 'mutual', 'non-disclosure', 'confidentiality', 'recitals', 'standard', 'governing', 'jpmorgan', 'chase', 'bank', 'beginning', 'ending', 'balance', 'deposits', 'additions', 'withdrawals', 'electronic', 'transfers', 'subscription', 'billed', 'lifetime', 'amount', 'due', 'subtotal', 'residential', 'commercial', 'lease', 'premises', 'deposit', 'utilities', 'closing', 'disclosure', 'settlement', 'trid', 'hud-1', 'purchase', 'price', 'escrow', 'funds', 'institutional', 'review', 'board', 'irb', 'national', 'institutes', 'health', 'nih', 'research', 'strategy', 'grant', 'adenocarcinoma', 'pancreatic', 'ductal', 'dana-farber', 'cancer', 'institute', 'harvard', 'department', 'homeland', 'cisa', 'controlled', 'unclassified', 'cui', 'foia', 'responsive', 'attestation', 'fedramp', 'ssp', 'package', 'moderate', 'impact', 'sshd', 'publickey', 'cron', 'systemd', 'failed', 'accepted', 'password', 'individual', 'income', 'totalsource', 'paychex', 'flex', 'lisinopril', 'metformin', 'atorvastatin', 'serum', 'creatinine', 'egfr', 'hba1c', 'vitals', 'copd', 'obstructive', 'pulmonary', 'disease', 'chronic', 'mri', 'brain', 'contrast', 'parenchyma', 'ventricles', 'fazekas', 'systems', 'distributed', 'event-driven', 'cfa', 'blackstone', 'morgan', 'chartered', 'confidential', 'information', 'cisa', 'attestation', 'sc-28', 'sp', '800-53', 'fedramp', 'clinicaltrials', 'nct', 'protocol', 'grant', 'r01', 'pancreatic', 'adenocarcinoma', 'dana-farber', 'harvard', 'cardiology', 'diverticulitis', 'resection', 'superbill', 'hcpcs', 'icd-10', 'progress', 'name', 'names', 'partner', 'partners', 'capital', 'adp', 'tax', 'taxes', 'inpatient', 'discharge', 'clinicaltrials.gov', 'id', 'ids', 'phd', 'md', 'do', 'jd', 'mba', 'cpa', 'pi', 'in', 'at', 'on', 'of', 'to', 'by', 'or', 'as', 'if', 'an', 'is', 'it', 'be', 'we', 'us', 'up', 'so', 'no', 'do', 'go', 'he', 'me', 'my',
581
707
  // Games, Chess, and Playing Pieces
582
708
  'bishop', 'bishops', 'knight', 'knights', 'rook', 'rooks', 'pawn', 'pawns', 'king', 'kings', 'queen', 'queens', 'chessboard', 'checkmate', 'stalemate', 'castling', 'en passant', 'chess',
583
709
  // Colors & Visual Descriptors
@@ -591,11 +717,77 @@ let NOT_NAME_WORDS = new Set([
591
717
  'f.3d', 'f.supp', 'u.s.c.', 'v.', 'plaintiff', 'defendant', 'v', 'u.s.', 'court', 'app.', 'reporter', 'cir.']);
592
718
 
593
719
  const PROFILE_JARGON = {
594
- medical: ['sleep', 'apnea', 'symptom', 'symptoms', 'trauma', 'hypertension', 'health', 'disease', 'condition', 'diagnosis', 'treatment', 'medication', 'dose', 'patient', 'clinic', 'surgery', 'therapy', 'alcohol', 'cannabis', 'blood', 'pressure', 'heart', 'rate', 'emergency', 'contact', 'relationship', 'type', 'diabetes', 'cancer', 'asthma', 'copd', 'covid', 'infection', 'syndrome', 'disorder', 'chronic', 'acute', 'illness', 'fever', 'allergy', 'pain', 'referral', 'referred', 'prescription', 'prescribed', 'doctor', 'physician', 'nurse', 'hospital', 'clinical', 'note', 'notes', 'dx', 'rx', 'tx', 'hx', 'px', 'sx', 'insurance', 'bcbs', 'bronchitis', 'amoxicillin', 'penicillin', 'antibiotic', 'antibiotics', 'vital', 'vitals', 'bp', 'hr', 'bpm', 'mmhg', 'allergies', 'dosage'],
595
- realestate: ['escrow', 'tenant', 'landlord', 'lease', 'mortgage', 'appraisal', 'broker', 'property', 'zoning', 'parcel', 'rent', 'buyer', 'seller', 'agent', 'listing'],
596
- legal: ['testator', 'notary', 'commission', 'county', 'court', 'affidavit', 'plaintiff', 'defendant', 'litigation', 'jurisdiction', 'agreement', 'contract', 'settlement', 'clause', 'article', 'section', 'matter', 'case'],
597
- hr: ['candidate', 'employee', 'payroll', 'benefits', 'salary', 'vacation', 'supervisor', 'subordinate', 'performance', 'appraisal', 'interview', 'resume', 'applicant'],
598
- sales: ['prospect', 'opportunity', 'quota', 'pipeline', 'deal', 'revenue', 'forecast', 'lead', 'churn', 'client', 'customer']
720
+ medical: [
721
+ 'sleep', 'apnea', 'symptom', 'symptoms', 'trauma', 'hypertension', 'health', 'disease', 'condition',
722
+ 'diagnosis', 'treatment', 'medication', 'dose', 'patient', 'clinic', 'surgery', 'therapy', 'alcohol',
723
+ 'cannabis', 'blood', 'pressure', 'heart', 'rate', 'emergency', 'contact', 'relationship', 'type',
724
+ 'diabetes', 'cancer', 'asthma', 'copd', 'covid', 'infection', 'syndrome', 'disorder', 'chronic', 'acute',
725
+ 'illness', 'fever', 'allergy', 'pain', 'referral', 'referred', 'prescription', 'prescribed', 'doctor',
726
+ 'physician', 'nurse', 'hospital', 'clinical', 'note', 'notes', 'dx', 'rx', 'tx', 'hx', 'px', 'sx',
727
+ 'insurance', 'bcbs', 'bronchitis', 'amoxicillin', 'penicillin', 'antibiotic', 'antibiotics', 'vital',
728
+ 'vitals', 'bp', 'hr', 'bpm', 'mmhg', 'allergies', 'dosage', 'parenchyma', 'ventricles', 'fazekas',
729
+ 'ischemia', 'lesion', 'cardiology', 'atherosclerotic', 'aortocoronary', 'bypass', 'graft', 'hyperlipidemia',
730
+ 'diverticulitis', 'resection', 'colon', 'superbill', 'encounter', 'cpt', 'hcpcs', 'icd-10'
731
+ ],
732
+ realestate: [
733
+ 'escrow', 'tenant', 'landlord', 'lease', 'mortgage', 'appraisal', 'broker', 'property', 'zoning',
734
+ 'parcel', 'rent', 'buyer', 'seller', 'agent', 'listing', 'residential', 'commercial', 'premises',
735
+ 'deposit', 'utilities', 'closing', 'disclosure', 'settlement', 'trid', 'hud-1', 'purchase', 'price',
736
+ 'funds', 'lender', 'deed', 'title', 'disbursement'
737
+ ],
738
+ legal: [
739
+ 'testator', 'notary', 'commission', 'county', 'court', 'affidavit', 'plaintiff', 'defendant',
740
+ 'litigation', 'jurisdiction', 'agreement', 'contract', 'settlement', 'clause', 'article', 'section',
741
+ 'matter', 'case', 'united', 'states', 'district', 'northern', 'southern', 'eastern', 'western',
742
+ 'division', 'complaint', 'violation', 'defend', 'trade', 'secrets', 'act', 'demand', 'jury', 'trial',
743
+ 'federal', 'question', 'diversity', 'citizenship', 'mutual', 'non-disclosure', 'confidentiality',
744
+ 'recitals', 'whereas', 'confidential', 'information', 'care', 'term', 'exhibit', 'party', 'parties',
745
+ 'disclosing', 'receiving', 'witnesseth', 'standard', 'indemnification', 'liability', 'governing',
746
+ 'law', 'docket', 'deponent', 'reporter', 'appearances', 'examination', 'services', 'scope', 'work',
747
+ 'master', 'msa'
748
+ ],
749
+ academic: [
750
+ 'institutional', 'review', 'board', 'irb', 'protocol', 'national', 'institutes', 'health', 'nih',
751
+ 'research', 'strategy', 'grant', 'adenocarcinoma', 'pancreatic', 'ductal', 'dana-farber', 'cancer',
752
+ 'institute', 'harvard', 'medical', 'school', 'application', 'study', 'title', 'identifier',
753
+ 'investigator', 'principal', 'investigators', 'sponsor', 'protection', 'confidentiality', 'harbor',
754
+ 'standards', 'clinical', 'trials', 'de-identification', 'aggregation', 'identifiers', 'aims',
755
+ 'sequencing', 'biomarkers', 'methylation'
756
+ ],
757
+ finance: [
758
+ 'jpmorgan', 'chase', 'bank', 'beginning', 'ending', 'balance', 'deposits', 'additions', 'withdrawals',
759
+ 'electronic', 'transfers', 'statement', 'customer', 'subscription', 'plan', 'billed', 'lifetime',
760
+ 'amount', 'due', 'subtotal', 'sales', 'tax', 'regular', 'pay', 'bonus', 'gross', 'net', 'earnings',
761
+ 'withholding', 'withheld', 'social', 'security', 'medicare', 'fica', 'oasdi', 'swt', 'fwt', 'direct',
762
+ 'deposit', 'checking', 'savings', 'account', 'invoice', 'currency', 'status', 'routing', 'check',
763
+ 'advice', 'summary', 'credit', 'debit'
764
+ ],
765
+ devops: [
766
+ 'failed', 'accepted', 'publickey', 'password', 'cron', 'systemd', 'sshd', 'authentication',
767
+ 'connection', 'timeout', 'cluster', 'postgres', 'postgresql', 'root', 'admin', 'syslog', 'daemon',
768
+ 'service', 'kubernetes', 'k8s', 'docker', 'container', 'pod', 'namespace', 'ingress', 'egress'
769
+ ],
770
+ compliance: [
771
+ 'department', 'homeland', 'security', 'cisa', 'controlled', 'unclassified', 'information', 'cui',
772
+ 'foia', 'responsive', 'record', 'ciso', 'attestation', 'fedramp', 'ssp', 'package', 'moderate',
773
+ 'impact', 'level', 'nist', 'sp', '800-53', 'sc-28', 'fips', '140-3', 'dhs', 'exemption', 'privacy',
774
+ 'mandate', 'statutory', 'declaration'
775
+ ],
776
+ support: [
777
+ 'ticket', 'status', 'priority', 'requester', 'assignee', 'organization', 'solved', 'open', 'pending',
778
+ 'incident', 'record', 'servicenow', 'zendesk', 'jira', 'rate', 'limit', 'quota', 'concurrency',
779
+ 'settings', 'access', 'connection', 'pool', 'exhaustion'
780
+ ],
781
+ hr: [
782
+ 'candidate', 'employee', 'payroll', 'benefits', 'salary', 'vacation', 'supervisor', 'subordinate',
783
+ 'performance', 'appraisal', 'interview', 'resume', 'applicant', 'engineer', 'developer', 'analyst',
784
+ 'specialist', 'director', 'manager', 'lead', 'staff', 'senior', 'junior', 'experience', 'education',
785
+ 'skills', 'certifications', 'summary', 'responsibilities'
786
+ ],
787
+ sales: [
788
+ 'prospect', 'opportunity', 'quota', 'pipeline', 'deal', 'revenue', 'forecast', 'lead', 'churn',
789
+ 'client', 'customer'
790
+ ]
599
791
  };
600
792
  // --- END DEFAULT RULES ---
601
793
 
@@ -635,10 +827,10 @@ const PROFILE_JARGON = {
635
827
  const PROFILE_ALIAS_MAP = {
636
828
  'general': 'general',
637
829
  'underwriting': 'underwriting', 'lending': 'underwriting', 'mortgage': 'underwriting', 'loan': 'underwriting', 'income': 'underwriting', 'income_verification': 'underwriting', 'payroll': 'underwriting', 'w2': 'underwriting', 'paystub': 'underwriting',
638
- 'medical': 'medical', 'healthcare': 'medical', 'health': 'medical', 'pharma': 'pharma',
639
- 'engineering': 'engineering', 'dev': 'engineering', 'devops': 'engineering', 'tech': 'tech',
640
- 'finance': 'finance', 'bizops': 'bizops', 'sales': 'sales', 'wealthmgmt': 'wealthmgmt', 'wealth': 'wealthmgmt', 'insurance': 'insurance', 'accounting': 'accounting',
641
- 'legal': 'legal', 'compliance': 'compliance', 'ccpa': 'ccpa',
830
+ 'medical': 'medical', 'healthcare': 'medical', 'health': 'medical', 'pharma': 'pharma', 'hipaa': 'medical',
831
+ 'engineering': 'engineering', 'dev': 'dev', 'api': 'dev', 'devops': 'engineering', 'tech': 'tech',
832
+ 'finance': 'finance', 'bizops': 'bizops', 'sales': 'sales', 'wealthmgmt': 'wealthmgmt', 'wealth': 'wealthmgmt', 'insurance': 'insurance', 'accounting': 'accounting', 'pci': 'finance',
833
+ 'legal': 'legal', 'compliance': 'compliance', 'ccpa': 'ccpa', 'gdpr': 'compliance', 'soc2': 'compliance', 'iso27001': 'compliance', 'nist': 'compliance', 'dpo': 'compliance', 'grc': 'compliance',
642
834
  'hr': 'hr', 'security': 'security', 'marketing': 'marketing', 'support': 'support',
643
835
  'realestate': 'realestate', 'academic': 'academic', 'agents': 'agents', 'ai_agents': 'agents', 'creative': 'creative', 'personal': 'personal'
644
836
  };
@@ -665,7 +857,7 @@ const PROFILE_JARGON = {
665
857
 
666
858
  function detectMatches(text, activeProfile = 'general', customRules = [], nlpNames = [], enabledEntities = null, mlEntities = []) {
667
859
  let textToProcess = text.replace(/[\u200b\u200c\u200d\ufeff]/g, '');
668
- textToProcess = textToProcess.replace(/([a-zA-Z])(Email|Phone|Mobile|Tel|Address|IP|ID|URL|SSN|Date):/g, '$1 $2:');
860
+ textToProcess = textToProcess.replace(/([a-z])(Email|Phone|Mobile|Tel|Address|IP|ID|URL|SSN|Date):/g, '$1 $2:');
669
861
 
670
862
  let matches = [];
671
863
 
@@ -722,13 +914,14 @@ const PROFILE_JARGON = {
722
914
  start = m.index + relOffset;
723
915
  }
724
916
  }
917
+ if (matchedText.trim().length < 2) continue;
725
918
  const end = start + matchedText.length;
726
919
 
727
920
  if (rule.type !== 'NAME' && rule.type !== 'ADDRESS') {
728
921
  const val = matchedText.toLowerCase().trim();
729
- if (NAME_STOP_LIST.has(val) || NOT_NAME_WORDS.has(val)) {
922
+ if (NOT_NAME_WORDS.has(val) || currentJargon.has(val)) {
730
923
  // Skip if generic English dictionary term matched by greedy regex (e.g. SWIFT matching SCRUBBER or CONTAINS)
731
- if (rule.type === 'FINANCIAL' || rule.type === 'ID' || rule.type === 'PRIVACY' || rule.type === 'SECRET') {
924
+ if (rule.type === 'FINANCIAL' || rule.type === 'ID' || rule.type === 'PRIVACY' || rule.type === 'SECRET' || rule.type === 'LEGAL' || rule.type === 'PHI') {
732
925
  continue;
733
926
  }
734
927
  }
@@ -738,7 +931,7 @@ const PROFILE_JARGON = {
738
931
  matchedText = matchedText.replace(/[.,;:]+$/, '').trim();
739
932
  }
740
933
  let val = matchedText.toLowerCase().trim();
741
- if (!val || NAME_STOP_LIST.has(val)) continue;
934
+ if (!val || NAME_STOP_LIST.has(val) || currentJargon.has(val) || NOT_NAME_WORDS.has(val)) continue;
742
935
 
743
936
  if (rule.type === 'NAME') {
744
937
  let words = val.split(/[ \t\xA0]+/);
@@ -757,28 +950,62 @@ const PROFILE_JARGON = {
757
950
  }
758
951
  }
759
952
  }
760
- if (!rule.isContextName && words.some(w => {
953
+ if (!rule.isContextName && (
954
+ words.some(w => {
955
+ const cleanW = w.replace(/[^\p{L}]/gu, '');
956
+ if (cleanW.length <= 1) return false;
957
+ return currentJargon.has(w) || NOT_NAME_WORDS.has(w) || NOT_NAME_WORDS.has(cleanW) || NAME_STOP_LIST.has(w) || NAME_STOP_LIST.has(cleanW);
958
+ }) ||
959
+ val.split(/[ \t\xA0-]+/).some(sw => {
960
+ const cleanSW = sw.replace(/[^\p{L}]/gu, '');
961
+ if (cleanSW.length <= 1) return false;
962
+ return currentJargon.has(sw) || NOT_NAME_WORDS.has(sw) || NOT_NAME_WORDS.has(cleanSW) || NAME_STOP_LIST.has(sw) || NAME_STOP_LIST.has(cleanSW);
963
+ })
964
+ )) continue;
965
+
966
+ if (rule.isAggressiveName) {
967
+ const lineStart = textToProcess.lastIndexOf('\n', start) + 1;
968
+ const lineEnd = textToProcess.indexOf('\n', end);
969
+ const fullLine = textToProcess.substring(lineStart, lineEnd === -1 ? textToProcess.length : lineEnd).trim();
970
+ if (fullLine.startsWith('|') || fullLine.startsWith('+') || fullLine.includes('===') || fullLine.includes('---')) {
971
+ continue;
972
+ }
973
+ }
974
+
975
+ if (rule.isContextName && words.length > 0 && words.some(w => {
761
976
  const cleanW = w.replace(/[^\p{L}]/gu, '');
762
- if (cleanW.length <= 1) return false;
763
- return currentJargon.has(w) || NOT_NAME_WORDS.has(w) || NOT_NAME_WORDS.has(cleanW) || NAME_STOP_LIST.has(w) || NAME_STOP_LIST.has(cleanW);
764
- })) continue;
977
+ if (rule.isCorporateName && (CORPORATE_SUFFIXES.has(cleanW) || US_STATES_SET.has(cleanW))) {
978
+ return false;
979
+ }
980
+ return !cleanW || currentJargon.has(w) || NOT_NAME_WORDS.has(w) || NOT_NAME_WORDS.has(cleanW) || NAME_STOP_LIST.has(w) || NAME_STOP_LIST.has(cleanW);
981
+ })) {
982
+ continue;
983
+ }
765
984
  } else if (rule.type === 'ADDRESS') {
766
985
  const cleanVal = val.replace(/[.,;!?]/g, ' ').trim();
767
- if (NAME_STOP_LIST.has(cleanVal) || currentJargon.has(cleanVal)) continue;
986
+ if (NAME_STOP_LIST.has(cleanVal) || currentJargon.has(cleanVal) || NOT_NAME_WORDS.has(cleanVal)) continue;
768
987
  }
769
988
 
770
- matches.push({ start, end: start + matchedText.length, value: matchedText, type: rule.type });
989
+ matches.push({ start, end: start + matchedText.length, value: matchedText, type: rule.type, isHighConfidence: !!rule.isContextName });
771
990
  }
772
991
  }
773
992
  });
774
993
 
775
994
  if (nlpNames && nlpNames.length > 0) {
776
995
  nlpNames.forEach(name => {
996
+ if (!name || typeof name !== 'string' || name.trim().length < 3) return;
997
+ const val = name.toLowerCase().trim();
998
+ if (NAME_STOP_LIST.has(val) || NOT_NAME_WORDS.has(val) || currentJargon.has(val)) return;
999
+ const words = val.split(/\s+/);
1000
+ if (words.some(w => {
1001
+ const cleanW = w.replace(/[^\p{L}]/gu, '');
1002
+ return !cleanW || NOT_NAME_WORDS.has(w) || NOT_NAME_WORDS.has(cleanW) || currentJargon.has(w) || currentJargon.has(cleanW) || NAME_STOP_LIST.has(w) || NAME_STOP_LIST.has(cleanW);
1003
+ })) return;
777
1004
  const safeName = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
778
1005
  const rx = new RegExp(`(?<=^|[^\\p{L}\\p{N}_])${safeName}(?=[^\\p{L}\\p{N}_]|$)`, 'gu');
779
1006
  let m;
780
1007
  while ((m = rx.exec(textToProcess)) !== null) {
781
- matches.push({ start: m.index, end: m.index + m[0].length, value: m[0], type: 'NAME' });
1008
+ matches.push({ start: m.index, end: m.index + m[0].length, value: m[0], type: 'NAME', isHighConfidence: true });
782
1009
  }
783
1010
  });
784
1011
  }
@@ -789,14 +1016,14 @@ const PROFILE_JARGON = {
789
1016
  const rx = new RegExp(`(?<=^|[^\\p{L}\\p{N}_])${safeName}(?=[^\\p{L}\\p{N}_]|$)`, 'giu');
790
1017
  let m;
791
1018
  while ((m = rx.exec(textToProcess)) !== null) {
792
- matches.push({ start: m.index, end: m.index + m[0].length, value: m[0], type: item.type });
1019
+ matches.push({ start: m.index, end: m.index + m[0].length, value: m[0], type: item.type, isHighConfidence: true });
793
1020
  }
794
1021
  });
795
1022
  }
796
1023
 
797
1024
  const learnedNames = new Set();
798
1025
  matches.forEach(m => {
799
- if (m.type === 'NAME') {
1026
+ if (m.type === 'NAME' && m.isHighConfidence) {
800
1027
  const nameWords = m.value.split(/[^\p{L}'-]+/u);
801
1028
  nameWords.forEach(w => {
802
1029
  if (w && w.length >= 2 && /^\p{Lu}/u.test(w)) {
@@ -937,7 +1164,7 @@ const PROFILE_JARGON = {
937
1164
  cleaned = cleaned.replace(/(?:^|\n)[a-zA-Z0-9_#.:\-*>[\]=\s,'"]+\{[^}]*(--[a-zA-Z0-9_-]+:|color-mix\(|var\()[^}]*\}/g, "");
938
1165
  }
939
1166
  // 2. Strip AI author prefixes and platform artifacts
940
- cleaned = cleaned.replace(/^\s*(?:Claude responded|Claude|ChatGPT|Gemini|Grok|DeepSeek|Kimi|Copilot|Assistant|User)\s*(?::|\bsaid\b|\bresponded\b|(?=\s))\s*/i, "");
1167
+ cleaned = cleaned.replace(/^\s*(?:Claude responded|Claude|ChatGPT|Gemini|Grok|DeepSeek|Kimi|Copilot|Assistant|User)\s*(?::|\bsaid\b|\bresponded\b|(?:\s*\n))\s*/i, "");
941
1168
  cleaned = cleaned.replace(/^(?:Here (?:is|are) (?:the )?(?:redacted|scrubbed|sanitized|processed|clean|updated|modified) (?:text|output|version|data).*?[:\n]+|\*\*Scrubbed Text\*\*[:\n]+|### Scrubbed Text[:\n]+)/i, '');
942
1169
  cleaned = cleaned.replace(/^\s*Edit\s*\n+/i, "");
943
1170
  cleaned = cleaned.replace(/\s*\bEdit\s+in\s+a\s+page\b\s*$/i, "");