@privacyscrubber/mcp-server 2.0.3 → 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.cjs 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.
@@ -31,14 +34,10 @@ let DEVOPS_SECRETS = [
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,45 +45,17 @@ 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}|\s+[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*)\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-]{3,30})\b/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 },
55
+
85
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 },
86
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 },
87
- { 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|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|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 },
88
59
  { type: 'ADDRESS', regex: /\b(?:P\.?O\.?[ \t\xA0]*Box|PO[ \t\xA0]*Box)[ \t\xA0]+\d{1,6}\b/gi },
89
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 },
90
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 },
@@ -98,24 +69,7 @@ let REGEX_RULES = [
98
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 },
99
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 },
100
71
 
101
- // PHI & Medical
102
- { type: 'PHI', regex: /\b(?:MRN|Patient ID|Medical Record (?:No\.?|Num(?:ber)?|#)|Patient (?:No\.?|Num(?:ber)?|#))[\s:#]+([A-Za-z0-9-]+)/gi },
103
- { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9-]{4,}\b/gi },
104
- { type: 'ID', regex: /\b(?:NPI|National Provider Identifier)[:\s#]*(\d{10})\b/gi },
105
- { type: 'ID', regex: /\b(?:Device\s+(?:Identifier|ID|Serial|No\.?|Number)|UDI)[:\s#]+([A-Za-z0-9-]+)/gi },
106
- { type: 'ID', regex: /\bUDI[-_][A-Za-z0-9-]+\b/gi },
107
- { type: 'ID', regex: /\b(?:Vehicle\s+(?:Serial|ID|Identification(?:\s+Number)?|No\.?|Number)|VIN)[:\s#]+([A-Za-z0-9-]+)/gi },
108
- { type: 'PHI', regex: /\b(?!NCT|INC|SEC|ISO|DOC|SOC|CPT)[A-Z]{2,3}\d{6,8}\b/g },
109
- { type: 'PHI', regex: /\bNHS[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}\b/gi },
110
-
111
- // Copyrights
112
- { type: 'COPYRIGHT', regex: /\bPROJECT[-_][A-Z0-9]{5,}\b/gi },
113
- { type: 'COPYRIGHT', regex: /\b(DRAFT|ASSET|SCRIPT)[-_][0-9]{4,}\b/gi },
114
-
115
72
  // General Privacy, Dates & Secrets
116
- { type: 'ID', regex: /\b(?:GDPR|HIPAA|CCPA|SOC2)[-_]AUDIT[-_]\d{4}\b/gi },
117
- { type: 'ID', regex: /\bPOLICY[-_][A-Z0-9]{5,}\b/gi },
118
- { type: 'ID', regex: /\bGRADE[S]?\s*:\s*[A-DF][+-]?\b/gi },
119
73
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
120
74
  { type: 'SECRET', regex: /\b(?:PASSWORD|PWD|SECRET)\s*[:=]\s*["']?[\S]{4,}["']?/gi },
121
75
 
@@ -139,6 +93,7 @@ let REGEX_RULES = [
139
93
 
140
94
  // Phone Numbers
141
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 },
142
97
  { type: 'PHONE', regex: /\+?[1-9]\d{1,3}[\s.-]\(?\d{1,4}\)?[\s.-]\d{2,4}[\s.-]\d{4}/g },
143
98
  { type: 'PHONE', regex: /(?:\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}\b/g },
144
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 },
@@ -185,28 +140,53 @@ let PROFILE_RULES = {
185
140
  { type: 'LEGAL', regex: /\bCASE[-_][A-Z0-9_-]{4,}\b/gi },
186
141
  { type: 'LEGAL', regex: /\bMATTER[-_][A-Z0-9_-]{4,}\b/gi },
187
142
  { type: 'LEGAL', regex: /\b[A-Z]{2,4}[- ]?\d{2}[- ]?\d{4,}\b/g },
188
- { 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 }
189
151
  ],
190
152
  hr: [
191
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 },
192
154
  { type: 'ID', regex: /\bEEID[ -]?\d{4,}\b/gi },
193
155
  { type: 'ID', regex: /\bEMP[-_]\d{3,}\b/gi },
194
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 },
195
162
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
196
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 },
197
164
  { type: 'ID', regex: /(?:https?:\/\/)?(?:www\.)?linkedin\.com\/in\/[A-Za-z0-9_-]+/gi },
198
165
  { type: 'ID', regex: /(?:https?:\/\/)?(?:www\.)?github\.com\/[A-Za-z0-9_-]+/gi },
199
- { 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 }
200
171
  ],
201
172
  finance: [
202
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 },
203
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 },
204
- { 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 }
205
185
  ],
206
186
  medical: [
207
187
  { type: 'PHI', regex: /\b(?:MRN|Patient ID|Medical Record (?:No\.?|Num(?:ber)?|#)|Patient (?:No\.?|Num(?:ber)?|#))[\s:#]+([A-Za-z0-9-]+)/gi },
208
188
  { type: 'DATE', regex: /\b(?:DOB|Date of Birth|BIRTHDAY)[\s:]+([0-9./-]{6,10})\b/gi },
209
- { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9-]{4,}\b/gi },
189
+ { type: 'PHI', regex: /\bMRN[-_ ]*[A-Za-z0-9_-]{4,}\b/gi },
210
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 },
211
191
  { type: 'ID', regex: /\b(?:Health\s+Plan(?:\s+Beneficiary)?|Beneficiary(?:\s+No\.?|\s+Number)?|HPN)[:\s#]+([A-Za-z0-9-]+)/gi },
212
192
  { type: 'ID', regex: /\bHPN[-_][A-Za-z0-9-]+\b/gi },
@@ -217,136 +197,265 @@ let PROFILE_RULES = {
217
197
  { type: 'ID', regex: /\b(?:Vehicle\s+(?:Serial|ID|Identification(?:\s+Number)?|No\.?|Number)|VIN)[:\s#]+([A-Za-z0-9-]+)/gi },
218
198
  { type: 'ID', regex: /\bVIN[-_][A-Za-z0-9-]+\b/gi },
219
199
  { type: 'PHI', regex: /\b(?!NCT|INC|SEC|ISO|DOC|SOC|CPT)[A-Z]{2,3}\d{6,8}\b/g },
220
- { type: 'PHI', regex: /\bNHS[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}\b/gi }
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 }
221
205
  ],
222
206
  security: [
223
- { 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 }
224
240
  ],
225
241
  marketing: [
226
242
  { type: 'ID', regex: /\b(?:LEAD|PROSPECT)[-_: ]*[A-Z0-9_-]*[0-9][A-Z0-9_-]*\b/gi },
227
243
  { type: 'ID', regex: /\b(?:CAMPAIGN|CLID|GCLID|FBCLID)[-_:=]*[A-Za-z0-9_-]{10,}\b/gi },
228
- { type: 'FINANCIAL', regex: /(?<=\b(?:LTV|CAC)[\s:]*)(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,.]+\b/gi },
229
- { 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 }
230
250
  ],
231
251
  bizops: [
232
- { type: 'ID', regex: /\b(?:DEAL|KPI|METRIC)[-_: ]?[A-Z0-9]{4,}\b/gi },
233
- { type: 'ID', regex: /\b(?:ENTITY|VENDOR|PARTNER)[-_: ]?[0-9]{4,10}\b/gi },
234
- { type: 'FINANCIAL', regex: /\b(?:REVENUE|EBITDA|PROFIT|MARGIN)[\s:_-]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.]+[KM]?\b/gi },
235
- { 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 }
236
263
  ],
237
264
  sales: [
238
- { 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 },
239
267
  { type: 'ID', regex: /\b(?:DOCUSIGN|CONTRACT)[-_: ]?[0-9A-F]{8,32}\b/gi },
240
- { type: 'FINANCIAL', regex: /\b(?:ARR|MRR|QUOTA)[\s:]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)?[0-9,.]+[KM]?\b/gi },
241
- { 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 }
242
273
  ],
243
274
  support: [
244
- { 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 },
245
276
  { type: 'ID', regex: /\b(?:ZENDESK|INTERCOM|JIRA)[-_:# ]?[0-9]{4,10}\b/gi },
246
- { type: 'ID', regex: /\b(?:REFUND|RETURN|RMA)[-_:# ]?[A-Z0-9]{6,12}\b/gi },
247
- { 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 }
248
282
  ],
249
283
  realestate: [
250
284
  { type: 'ID', regex: /\b(?:MLS|LIS)[- ]?\d{6,10}\b/gi },
251
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 },
252
287
  { type: 'ID', regex: /\bTENANT[-_]ID[-_][0-9]{4,}\b/gi },
253
- { type: 'FINANCIAL', regex: /(?<=\b(?:RENT|LEASE|ESCROW)[\s:]+)(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[0-9,]{3,}(?:\.\d{2})?\b/gi },
254
- { 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 }
255
293
  ],
256
294
  compliance: [
257
- { type: 'SECRET', regex: /\b(?:GDPR|HIPAA|CCPA|SOC2|ISO27001)[-_: ]?AUDIT[-_: ]?\d{4}\b/gi },
258
- { type: 'SECRET', regex: /\b(?:DPA|POLICY)[-_: ]?[A-Z0-9]{5,15}\b/gi },
259
- { type: 'ID', regex: /\b(?:SAR|DSAR)(?:[-_\/: ]+[A-Z0-9/_-]+|[0-9][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 }
260
306
  ],
261
307
  ccpa: [
262
- { type: 'ID', regex: /\b(?:DL|DRIVER['’]?S?\s+LICENSE)[:\s#-]*[A-Z0-9]{6,12}\b/gi },
263
- { 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 },
264
310
  { type: 'ID', regex: /\b(?:CCPA|CPRA)[-_: ]?OPT[-_ ]OUT\b/gi },
265
- { 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 }
266
314
  ],
267
315
  engineering: [
316
+ ...DEVOPS_SECRETS,
268
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 },
269
318
  { type: 'ID', regex: /\b[a-z0-9._-]+\/[a-z0-9._-]+:[a-z0-9._-]+\b/g },
270
319
  { type: 'ID', regex: /\b[a-fA-F0-9]{40}\b/g },
271
- { 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 }
272
323
  ],
273
324
  agents: [
274
- { type: 'ID', regex: /\b(?:AGENT|VECTOR|EMBEDDING)[-_: ]?(?:ID[-_: ]?)?[A-Z0-9]{8,}\b/gi },
275
- { type: 'ID', regex: /\bTASK[-_: ]?[A-Z0-9]{5,15}\b/gi },
276
- { 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 }
277
336
  ],
278
337
  academic: [
279
- { type: 'ID', regex: /\b(?:STUDENT|ALUMNI)[-_:# ]?[0-9]{5,10}\b/gi },
280
- { type: 'ID', regex: /\bCOURSE[-_:# ]?[A-Z]{3,4}[ ]?[0-9]{3,4}\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 },
281
340
  { type: 'ID', regex: /\b(?:FERPA|IRB)[-_:# ]*[A-Z0-9_-]*\d[A-Z0-9_-]*\b/gi },
282
- { type: 'ID', regex: /\bGRADE[S]?[\s:][A-DF][+-]?\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 }
283
350
  ],
284
351
  creative: [
285
- { 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 },
286
353
  { type: 'SECRET', regex: /\b(?:SPOILER|UNRELEASED|EMBARGOED)\b/gi },
287
- { 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 }
288
364
  ],
289
365
  tech: [
290
- { type: 'ID', regex: /\b(?:INSTANCE|NODE|CLUSTER)[-_]ID[-_][a-z0-9-]{10,}\b/gi },
291
- { type: 'ID', regex: /\bENV[-_: ]?(?:PROD|STAGING|DEV|TEST|QA)\b/gi },
292
- { 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 }
293
374
  ],
294
375
  personal: [
295
376
  { type: 'DATE', regex: /\b(?:DOB|BIRTHDAY|Date of Birth)[\s:]+([0-9./-]{6,10})\b/gi },
296
377
  { type: 'SECRET', regex: /\b(?:PASSWORD|PWD|SECRET|PIN)[\s:]*[\S]{4,20}\b/gi },
297
- { 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 }
298
384
  ],
299
385
  wealthmgmt: [
300
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 },
301
387
  // Mixed-Caps name: All-Caps first name (3+ chars) + optional initials + Mixed-Case last name
302
388
  // Handles PDF-rendered trust names where OCR/extraction produces e.g. "KKKKK I. Mmmmmmm"
303
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 },
304
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 },
305
395
  { type: 'FINANCIAL', regex: /\b(?:Account|Acct\.?)[:\s#]*\d{4}[-\s]?\d{4}[-\s]?\d{2,6}\b/gi },
306
396
  { type: 'FINANCIAL', regex: /\b(?:Policy|Contract)\s*(?:No\.?|Number|#)[:\s]+[A-Z0-9][A-Z0-9\-]{3,14}\b/gi },
307
397
  { type: 'ID', regex: /\bCRD\s*#?\s*\d{4,8}\b/gi },
308
- { 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 },
309
- { 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 },
310
- { 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 }
311
405
  ],
312
406
  insurance: [
313
- { type: 'ID', regex: /\b(?:Claim|CLM)[:\s#-]*[A-Z0-9]{6,15}\b/gi },
314
- { type: 'ID', regex: /\b(?:Policy|POL)[:\s#-]*[A-Z]{0,4}[-]?\d{6,12}\b/gi },
315
- { type: 'FINANCIAL', regex: /\b(?:Loss|Claim\s+Amount|Settlement|Reserve|Indemnity)[:\s]+(?:[$€£¥₪₽₹]|(?:USD|EUR|GBP|CHF|ILS|RUB)\s?)[\d,]+(?:[.]\d{2})?\b/gi },
316
- { type: 'ID', regex: /\b(?:Adjuster\s+(?:ID|No)|Claim\s+Rep(?:\.|resentative)?)[:\s#]*[A-Z0-9]{4,12}\b/gi },
317
- { type: 'ID', regex: /\bNAIC[:\s#]*\d{5}\b/gi },
318
- { 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 },
319
413
  { type: 'ID', regex: /\b[A-HJ-NPR-Z0-9]{17}\b/g },
320
414
  { type: 'ID', regex: /\b(?:Insured|Named\s+Insured)[:\s]+[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+/g },
321
- { 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 }
322
420
  ],
323
421
  accounting: [
324
422
  { type: 'ID', regex: /\b(?:EIN|FEIN|Tax\s+ID)[:\s#]*\d{2}-\d{7}\b/gi },
325
- { 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 },
326
- { 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 },
327
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 },
328
- { 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 },
329
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 },
330
- { 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 },
331
- { 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 }
332
433
  ],
333
434
  pharma: [
334
- { 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 },
335
436
  { type: 'ID', regex: /\b(?:Protocol|Study)\s*(?:No|Number|ID)[:\s#]*[A-Z0-9][-A-Z0-9]{3,15}\b/gi },
336
437
  { type: 'ID', regex: /\b(?:IND|NDA|BLA|ANDA)\s*(?:No|Number|#)?[:\s]*\d{3,6}\b/gi },
337
- { type: 'ID', regex: /\bIRB[:\s#]*[A-Z0-9]{4,12}\b/gi },
338
- { type: 'ID', regex: /\b(?:Site\s+(?:No|ID)|Investigator\s+Site)[:\s#]*\d{3,6}\b/gi },
339
- { 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 },
340
441
  { type: 'PHI', regex: /\b(?:Dose|Dosage)[:\s]+\d+(?:\.\d+)?\s*(?:mg|mcg|mL|IU|units?)\b/gi },
341
- { 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 }
342
451
  ],
343
452
  underwriting: [
344
453
  // Employer Corporate / Business Names
345
- { 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 },
346
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 },
347
456
 
348
457
  // W-2 & Tax Identifiers
349
- { 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 },
350
459
  { type: 'ID', regex: /\b(?:EIN|FEIN|Tax\s+ID)[:\s#]*\d{2}-\d{7}\b/gi },
351
460
  { type: 'ID', regex: /\b\d{2}-\d{7}\b/g },
352
461
  { type: 'ID', regex: /\b\d{3}-\d{2}-\d{4}\b/g },
@@ -354,7 +463,7 @@ let PROFILE_RULES = {
354
463
 
355
464
  // Employee, Loan & Payroll IDs
356
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 },
357
- { type: 'ID', regex: /\b(?:Pay\s+Group|Cost\s+Center|Dept|Department)(?:[:#][\s#]*[A-Za-z0-9_-]{2,30}|\s+[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*)\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 },
358
467
  { type: 'ID', regex: /\b(?:Loan|Application|Deal|Borrower|File)\s*(?:#|ID|No\.?|Number)[:\s#]*[A-Za-z0-9-]{4,25}\b/gi },
359
468
 
360
469
  // Direct Deposit, Bank Accounts & Routing Numbers (Masked & Unmasked)
@@ -369,7 +478,7 @@ let PROFILE_RULES = {
369
478
 
370
479
  // Addresses & Locations
371
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 },
372
- { 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 },
373
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 },
374
483
  { type: 'ADDRESS', regex: /\b\d{5}-\d{4}\b/g },
375
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 }
@@ -420,7 +529,7 @@ let NAME_STOP_LIST = new Set([
420
529
  'step 1', 'step 2', 'step 3', 'step 4', 'step 5',
421
530
  'page 1', 'page 2', 'page 3', 'page 4', 'page 5',
422
531
  'cs101', 'course cs101',
423
- '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',
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',
424
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',
425
534
  'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december',
426
535
  'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday',
@@ -460,12 +569,26 @@ let NAME_STOP_LIST = new Set([
460
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',
461
570
  'wages', 'wage', 'tips', 'compensation', 'withheld', 'withholding', 'medicare', 'deductions', 'deduction',
462
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',
463
- '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', 'contact', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint']);
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']);
574
+
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']);
464
577
 
465
- 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', 'contact', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint']);
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
+ ]);
466
587
 
467
588
  let NOT_NAME_WORDS = new Set([
468
- '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', 'contact', 'keywords', 'keyword', 'keys', 'key', 'separation', 'pre-print', 'preprint',
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',
469
592
  // Grammatical & Sentence Starters
470
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",
471
594
  // Verbs, Auxiliaries, Commands & Imperatives
@@ -569,6 +692,7 @@ let NOT_NAME_WORDS = new Set([
569
692
 
570
693
  // General Academic & Professional vocabulary
571
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',
572
696
  // Quality & Adjectives
573
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',
574
698
  // Common Resume / Business Phrases
@@ -704,7 +828,7 @@ const PROFILE_JARGON = {
704
828
  'general': 'general',
705
829
  'underwriting': 'underwriting', 'lending': 'underwriting', 'mortgage': 'underwriting', 'loan': 'underwriting', 'income': 'underwriting', 'income_verification': 'underwriting', 'payroll': 'underwriting', 'w2': 'underwriting', 'paystub': 'underwriting',
706
830
  'medical': 'medical', 'healthcare': 'medical', 'health': 'medical', 'pharma': 'pharma', 'hipaa': 'medical',
707
- 'engineering': 'engineering', 'dev': 'engineering', 'devops': 'engineering', 'tech': 'tech',
831
+ 'engineering': 'engineering', 'dev': 'dev', 'api': 'dev', 'devops': 'engineering', 'tech': 'tech',
708
832
  'finance': 'finance', 'bizops': 'bizops', 'sales': 'sales', 'wealthmgmt': 'wealthmgmt', 'wealth': 'wealthmgmt', 'insurance': 'insurance', 'accounting': 'accounting', 'pci': 'finance',
709
833
  'legal': 'legal', 'compliance': 'compliance', 'ccpa': 'ccpa', 'gdpr': 'compliance', 'soc2': 'compliance', 'iso27001': 'compliance', 'nist': 'compliance', 'dpo': 'compliance', 'grc': 'compliance',
710
834
  'hr': 'hr', 'security': 'security', 'marketing': 'marketing', 'support': 'support',
@@ -733,7 +857,7 @@ const PROFILE_JARGON = {
733
857
 
734
858
  function detectMatches(text, activeProfile = 'general', customRules = [], nlpNames = [], enabledEntities = null, mlEntities = []) {
735
859
  let textToProcess = text.replace(/[\u200b\u200c\u200d\ufeff]/g, '');
736
- 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:');
737
861
 
738
862
  let matches = [];
739
863
 
@@ -795,7 +919,7 @@ const PROFILE_JARGON = {
795
919
 
796
920
  if (rule.type !== 'NAME' && rule.type !== 'ADDRESS') {
797
921
  const val = matchedText.toLowerCase().trim();
798
- if (NAME_STOP_LIST.has(val) || NOT_NAME_WORDS.has(val) || currentJargon.has(val)) {
922
+ if (NOT_NAME_WORDS.has(val) || currentJargon.has(val)) {
799
923
  // Skip if generic English dictionary term matched by greedy regex (e.g. SWIFT matching SCRUBBER or CONTAINS)
800
924
  if (rule.type === 'FINANCIAL' || rule.type === 'ID' || rule.type === 'PRIVACY' || rule.type === 'SECRET' || rule.type === 'LEGAL' || rule.type === 'PHI') {
801
925
  continue;
@@ -839,8 +963,20 @@ const PROFILE_JARGON = {
839
963
  })
840
964
  )) continue;
841
965
 
842
- if (rule.isContextName && words.length > 0 && words.every(w => {
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 => {
843
976
  const cleanW = w.replace(/[^\p{L}]/gu, '');
977
+ if (rule.isCorporateName && (CORPORATE_SUFFIXES.has(cleanW) || US_STATES_SET.has(cleanW))) {
978
+ return false;
979
+ }
844
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);
845
981
  })) {
846
982
  continue;
@@ -850,7 +986,7 @@ const PROFILE_JARGON = {
850
986
  if (NAME_STOP_LIST.has(cleanVal) || currentJargon.has(cleanVal) || NOT_NAME_WORDS.has(cleanVal)) continue;
851
987
  }
852
988
 
853
- 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 });
854
990
  }
855
991
  }
856
992
  });
@@ -861,12 +997,15 @@ const PROFILE_JARGON = {
861
997
  const val = name.toLowerCase().trim();
862
998
  if (NAME_STOP_LIST.has(val) || NOT_NAME_WORDS.has(val) || currentJargon.has(val)) return;
863
999
  const words = val.split(/\s+/);
864
- if (words.every(w => NOT_NAME_WORDS.has(w) || currentJargon.has(w) || NAME_STOP_LIST.has(w))) return;
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;
865
1004
  const safeName = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
866
1005
  const rx = new RegExp(`(?<=^|[^\\p{L}\\p{N}_])${safeName}(?=[^\\p{L}\\p{N}_]|$)`, 'gu');
867
1006
  let m;
868
1007
  while ((m = rx.exec(textToProcess)) !== null) {
869
- 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 });
870
1009
  }
871
1010
  });
872
1011
  }
@@ -877,14 +1016,14 @@ const PROFILE_JARGON = {
877
1016
  const rx = new RegExp(`(?<=^|[^\\p{L}\\p{N}_])${safeName}(?=[^\\p{L}\\p{N}_]|$)`, 'giu');
878
1017
  let m;
879
1018
  while ((m = rx.exec(textToProcess)) !== null) {
880
- 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 });
881
1020
  }
882
1021
  });
883
1022
  }
884
1023
 
885
1024
  const learnedNames = new Set();
886
1025
  matches.forEach(m => {
887
- if (m.type === 'NAME') {
1026
+ if (m.type === 'NAME' && m.isHighConfidence) {
888
1027
  const nameWords = m.value.split(/[^\p{L}'-]+/u);
889
1028
  nameWords.forEach(w => {
890
1029
  if (w && w.length >= 2 && /^\p{Lu}/u.test(w)) {
@@ -1025,7 +1164,7 @@ const PROFILE_JARGON = {
1025
1164
  cleaned = cleaned.replace(/(?:^|\n)[a-zA-Z0-9_#.:\-*>[\]=\s,'"]+\{[^}]*(--[a-zA-Z0-9_-]+:|color-mix\(|var\()[^}]*\}/g, "");
1026
1165
  }
1027
1166
  // 2. Strip AI author prefixes and platform artifacts
1028
- 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, "");
1029
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, '');
1030
1169
  cleaned = cleaned.replace(/^\s*Edit\s*\n+/i, "");
1031
1170
  cleaned = cleaned.replace(/\s*\bEdit\s+in\s+a\s+page\b\s*$/i, "");