phase 1.6 gate 4: REMOVE name → ethnicity / gender inference
Per docs/PHASE_1_6_BIPA_GATES.md Gate 4 + AUDIT_TRAIL_PRD §4 protected- attribute exclusion rule. The lookup tables + inference functions in search.html (3375-3499) and console.html (245-311) were dead code in the rendering path — headshot rendering disabled 2026-04-28 left these functions defined but unused. Removing them forecloses both Title VII discriminatory-feature-engineering AND BIPA biometric-information- derived-from-biometric-identifier arguments. Removed: - FEMALE_NAMES, MALE_NAMES, NAMES_HISPANIC, NAMES_BLACK, NAMES_SOUTH_ASIAN, NAMES_EAST_ASIAN, NAMES_MIDDLE_EASTERN - SURNAMES_HISPANIC, SURNAMES_SOUTH_ASIAN, SURNAMES_EAST_ASIAN, SURNAMES_MIDDLE_EASTERN, SURNAMES_BLACK - guessGenderFromFirstName(), guessEthnicityFromName(), guessEthnicityFromFirstName(), genderFor() From both search.html and console.html. Replacement: deprecation comment block referencing the BIPA gates doc. Verified: zero live consumers anywhere in mcp-server/. Searched for genderFor()/guessEthnicityFromName()/guessEthnicityFromFirstName()/ guessGenderFromFirstName() call sites — none remain. Per J 2026-05-03: this kind of test-code-leaked-into-main is exactly what J wants cleaned up. The face-pool inference was meant as a testing tool for synthetic icon generation but ended up as production-shape inference logic in the customer-facing UI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cd440d4cee
commit
0c74b82fc8
@ -238,77 +238,10 @@ function roleBand(role){
|
||||
// the left edge + uppercase role pill in the detail line. Used by
|
||||
// every chapter that renders worker rows. `name` and `role` drive the
|
||||
// classification; `detail` is the full text after the pill.
|
||||
// Quick first-name → gender hint for face-pool selection. Same lookup
|
||||
// idea as the dashboard; if the name is unknown, the server falls back
|
||||
// to the full pool. Trimmed table — covers the most common names that
|
||||
// appear in the synthetic worker data.
|
||||
var FEMALE_NAMES = new Set(['Mary','Patricia','Jennifer','Linda','Elizabeth','Barbara','Susan','Jessica','Sarah','Karen','Lisa','Nancy','Betty','Sandra','Margaret','Ashley','Kimberly','Emily','Donna','Michelle','Carol','Amanda','Melissa','Deborah','Stephanie','Dorothy','Rebecca','Sharon','Laura','Cynthia','Amy','Kathleen','Angela','Shirley','Brenda','Emma','Anna','Pamela','Nicole','Samantha','Katherine','Christine','Helen','Debra','Rachel','Carolyn','Janet','Maria','Catherine','Heather','Diane','Olivia','Julie','Joyce','Victoria','Ruth','Virginia','Lauren','Kelly','Christina','Joan','Evelyn','Judith','Andrea','Hannah','Megan','Cheryl','Jacqueline','Martha','Madison','Teresa','Gloria','Sara','Janice','Ann','Kathryn','Abigail','Sophia','Frances','Jean','Alice','Judy','Isabella','Julia','Grace','Amber','Denise','Danielle','Marilyn','Beverly','Charlotte','Natalie','Theresa','Diana','Brittany','Kayla','Alexis','Lori','Marie','Carmen','Aisha','Rosa','Mia','Audrey','Erin','Tina','Vanessa','Tara','Wendy','Tanya','Maya','Crystal','Yvonne','Kara','Shannon','Brianna','Faith','Caroline','Carla','Tracey','Tracy','Rita','Dawn','Tiffany','Stacy','Stacey','Gina','Bonnie','Tammy','Joanne','Jamie','Tonya','Alyssa','Ariana','Elena','Ellie','Erica','Erika','Felicia','Holly','Jenna','Jenny','Krista','Kristen','Kristin','Krystal','Lana','Leah','Lucy','Mallory','Melinda','Meredith','Misty','Monica','Naomi','Paige','Paula','Renee','Rhonda','Robin','Roxanne','Selena','Sierra','Skylar','Sonia','Stella','Tamara','Veronica','Vivian','Whitney','Yolanda','Zoe']);
|
||||
var MALE_NAMES = new Set(['James','Robert','John','Michael','David','William','Richard','Joseph','Thomas','Charles','Christopher','Daniel','Matthew','Anthony','Mark','Donald','Steven','Paul','Andrew','Joshua','Kenneth','Kevin','Brian','George','Edward','Ronald','Timothy','Jason','Jeffrey','Ryan','Jacob','Gary','Nicholas','Eric','Jonathan','Stephen','Larry','Justin','Scott','Brandon','Benjamin','Samuel','Gregory','Frank','Alexander','Raymond','Patrick','Jack','Dennis','Jerry','Tyler','Aaron','Jose','Adam','Henry','Nathan','Douglas','Zachary','Peter','Kyle','Walter','Ethan','Jeremy','Harold','Keith','Christian','Roger','Noah','Gerald','Carl','Terry','Sean','Austin','Arthur','Lawrence','Jesse','Dylan','Bryan','Joe','Jordan','Billy','Bruce','Albert','Willie','Gabriel','Logan','Alan','Juan','Wayne','Roy','Ralph','Randy','Eugene','Vincent','Russell','Elijah','Louis','Bobby','Philip','Johnny','Marcus','Antonio','Carlos','Diego','Hector','Jorge','Julio','Manuel','Miguel','Pedro','Raul','Ricardo','Roberto','Sergio','Victor','Jamal','Xavier','DeShawn','Dwayne','Jermaine','Malik','Tyrone','Devon','Andre','Brent','Calvin','Casey','Cody','Cole','Cory','Dale','Damon','Darius','Darrell','Dean','Derek','Drew','Earl','Eddie','Floyd','Glenn','Greg','Howard','Ivan','Jared','Jay','Jeff','Joel','Lance','Lee','Leonard','Lloyd','Mario','Martin','Mason','Maurice','Max','Mitchell','Morgan','Nick','Norman','Oliver','Owen','Pete','Quincy','Rafael','Reggie','Rex','Ricky','Russ','Shane','Shaun','Stanley','Steve','Theodore','Todd','Travis','Trevor','Troy','Wade','Warren','Wesley']);
|
||||
function guessGenderFromFirstName(n){
|
||||
if(!n) return null;
|
||||
var clean=n.replace(/[^A-Za-z]/g,'');
|
||||
if(!clean) return null;
|
||||
var c=clean[0].toUpperCase()+clean.slice(1).toLowerCase();
|
||||
if(FEMALE_NAMES.has(c)) return 'woman';
|
||||
if(MALE_NAMES.has(c)) return 'man';
|
||||
return null;
|
||||
}
|
||||
function genderFor(name){
|
||||
var g = guessGenderFromFirstName(name);
|
||||
if(g) return g;
|
||||
if(!name) return 'man';
|
||||
var s=String(name); var h=0;
|
||||
for(var i=0;i<s.length;i++) h=(h*31+s.charCodeAt(i))|0;
|
||||
return (Math.abs(h)&1)?'man':'woman';
|
||||
}
|
||||
// Confident first-name → ethnicity. Synthetic data — we own the call.
|
||||
var NAMES_SOUTH_ASIAN_C=new Set(['Raj','Anil','Rohan','Vikram','Arjun','Sanjay','Ravi','Krishna','Pradeep','Sunil','Amit','Deepak','Ashok','Manoj','Rahul','Vijay','Suresh','Naveen','Anand','Nikhil','Aditya','Karan','Rajesh','Priya','Anjali','Neha','Kavya','Pooja','Divya','Meera','Lakshmi','Rani','Asha','Saanvi','Aanya','Aaradhya','Shreya','Riya','Tanvi','Ishita','Aarav','Ishaan','Shivani']);
|
||||
var NAMES_EAST_ASIAN_C=new Set(['Wei','Mei','Yi','Jin','Chen','Lin','Liu','Wang','Zhang','Yang','Wu','Zhao','Sun','Hiroshi','Yuki','Akira','Kenji','Sakura','Aiko','Haruto','Sora','Hyun','Eun','Yoon','Kai','Long','Hong','Xiu','Lan','Hua','Hao','Tao','Bao','Cheng','Feng','Jian','Dong','Bin','Min','Lei','Hui','Yu','Xin','Ying','Zhen','Yuan','Yan']);
|
||||
var NAMES_HISPANIC_C=new Set(['Carmen','Carlos','Maria','Diego','Hector','Jorge','Julio','Manuel','Miguel','Pedro','Raul','Ricardo','Roberto','Sergio','Antonio','Esperanza','Luz','Sofia','Lucia','Isabella','Camila','Valentina','Mariana','Elena','Rosa','Catalina','Esteban','Fernando','Eduardo','Javier','Alejandro','Andres','Mateo','Santiago','Sebastian','Emilio','Tomas','Cristina','Daniela','Gabriela','Ximena','Adriana','Beatriz','Pilar','Mercedes','Xavier','Marisol','Guadalupe','Lupita','Inez','Itzel','Yesenia','Joaquin','Ignacio','Rafael','Salvador','Cesar','Arturo','Armando','Hugo','Marco','Alejandra','Felipe','Gerardo','Jaime','Leonardo','Luis','Pablo','Ramon']);
|
||||
var NAMES_BLACK_C=new Set(['DeShawn','Jamal','Aisha','Latoya','Tyrone','Malik','Imani','Keisha','Tariq','Lakisha','Kenya','Tamika','Andre','Marcus','Demetrius','Jermaine','Reggie','Tyrese','Darius','Trevon','Kareem','Damon','Jalen','Jaylen','Dwayne','DaQuan','Aaliyah','Kiara','Janelle','Jasmine','Tanisha','Maurice','Tyrell','Kwame','Khalil','Terrell','Cedric','Nia','Zuri','Jada','Ebony','Dominique']);
|
||||
var NAMES_MIDDLE_EASTERN_C=new Set(['Layla','Omar','Khalid','Fatima','Yasmin','Hassan','Hussein','Ahmed','Mohamed','Mohammed','Ali','Karim','Yusuf','Yara','Nadia','Zainab','Rania','Samira','Mariam','Salma','Ibrahim','Mahmoud','Saif','Anwar','Bilal','Faisal','Hamza','Imran','Sami','Wael','Zaid','Amira','Iman','Lina','Mona','Noor','Rana','Soha','Zara']);
|
||||
// Surname → ethnicity. Surname is more diagnostic than first name
|
||||
// for hispanic and asian — "Anna Cruz" is hispanic via surname.
|
||||
var SURNAMES_HISPANIC_C=new Set(['Garcia','Rodriguez','Martinez','Hernandez','Lopez','Gonzalez','Perez','Sanchez','Ramirez','Torres','Flores','Rivera','Gomez','Diaz','Reyes','Cruz','Morales','Ortiz','Gutierrez','Chavez','Ramos','Ruiz','Alvarez','Mendoza','Vasquez','Castillo','Jimenez','Moreno','Romero','Herrera','Medina','Aguilar','Vargas','Castro','Fernandez','Guzman','Munoz','Salazar','Ortega','Delgado','Estrada','Ayala','Pena','Cabrera','Alvarado','Espinoza','Padilla','Cardenas','Cortes','Ibarra','Vega','Soto','Lara','Navarro','Campos','Acosta','Rios','Marquez','Sandoval','Maldonado','Solis','Rojas','Mejia','Beltran','Cervantes','Lozano','Carrillo','Trevino','Robles','Tapia','Lugo']);
|
||||
var SURNAMES_SOUTH_ASIAN_C=new Set(['Patel','Singh','Kumar','Sharma','Gupta','Shah','Mehta','Desai','Joshi','Reddy','Nair','Iyer','Verma','Agarwal','Kapoor','Chopra','Malhotra','Banerjee','Chatterjee','Mukherjee','Das','Sen','Bose','Roy','Sinha','Trivedi','Pandey','Mishra','Tiwari','Yadav','Chauhan','Rana','Thakur','Pillai','Menon','Krishnan','Rao','Naidu','Pradhan','Acharya','Devi','Kaur']);
|
||||
var SURNAMES_EAST_ASIAN_C=new Set(['Chen','Wang','Li','Liu','Yang','Huang','Zhao','Wu','Zhou','Xu','Zhu','Sun','Ma','Lin','Lee','Kim','Park','Choi','Jung','Kang','Cho','Yoon','Han','Lim','Oh','Nakamura','Tanaka','Suzuki','Yamamoto','Sato','Watanabe','Takahashi','Kobayashi','Yoshida','Saito','Nguyen','Tran','Le','Pham','Hoang','Phan','Vu','Vo','Dang','Bui','Do','Ngo','Truong','Mai','Cao','Wong','Tang','Tan','Cheng','Lau','Leung','Ng','Cheung','Yip','Hsu','Tsai','Hsieh']);
|
||||
var SURNAMES_MIDDLE_EASTERN_C=new Set(['Khan','Ahmed','Hussein','Hassan','Ali','Mahmoud','Mohamed','Mohammed','Saleh','Aziz','Karim','Hamad','Najjar','Haddad','Khoury','Mansour','Rahman','Iqbal','Malik','Sheikh','Siddiqui','Qureshi','Saeed']);
|
||||
|
||||
function guessEthnicityFromName(first, last){
|
||||
if(last){
|
||||
var s=last.replace(/[^A-Za-z]/g,'');
|
||||
if(s){
|
||||
var sc=s[0].toUpperCase()+s.slice(1).toLowerCase();
|
||||
if(SURNAMES_HISPANIC_C.has(sc)) return 'hispanic';
|
||||
if(SURNAMES_MIDDLE_EASTERN_C.has(sc)) return 'middle_eastern';
|
||||
if(SURNAMES_SOUTH_ASIAN_C.has(sc)) return 'south_asian';
|
||||
if(SURNAMES_EAST_ASIAN_C.has(sc)) return 'east_asian';
|
||||
}
|
||||
}
|
||||
if(first){
|
||||
var clean=first.replace(/[^A-Za-z]/g,'');
|
||||
if(clean){
|
||||
var c=clean[0].toUpperCase()+clean.slice(1).toLowerCase();
|
||||
if(NAMES_MIDDLE_EASTERN_C.has(c)) return 'middle_eastern';
|
||||
if(NAMES_BLACK_C.has(c)) return 'black';
|
||||
if(NAMES_HISPANIC_C.has(c)) return 'hispanic';
|
||||
if(NAMES_SOUTH_ASIAN_C.has(c)) return 'south_asian';
|
||||
if(NAMES_EAST_ASIAN_C.has(c)) return 'east_asian';
|
||||
}
|
||||
}
|
||||
return 'caucasian';
|
||||
}
|
||||
function guessEthnicityFromFirstName(n){
|
||||
if(!n) return 'caucasian';
|
||||
var clean=n.replace(/[^A-Za-z]/g,''); if(!clean) return 'caucasian';
|
||||
var c=clean[0].toUpperCase()+clean.slice(1).toLowerCase();
|
||||
if(NAMES_MIDDLE_EASTERN_C.has(c)) return 'middle_eastern';
|
||||
if(NAMES_BLACK_C.has(c)) return 'black';
|
||||
if(NAMES_HISPANIC_C.has(c)) return 'hispanic';
|
||||
if(NAMES_SOUTH_ASIAN_C.has(c)) return 'south_asian';
|
||||
if(NAMES_EAST_ASIAN_C.has(c)) return 'east_asian';
|
||||
return 'caucasian';
|
||||
}
|
||||
// Name → ethnicity / gender inference — REMOVED 2026-05-03 per Phase 1.6
|
||||
// BIPA gates (docs/PHASE_1_6_BIPA_GATES.md, Gate 4). Mirror of the same
|
||||
// removal in mcp-server/search.html. Functions had no live consumers
|
||||
// (headshot rendering disabled 2026-04-28). Do NOT re-introduce.
|
||||
|
||||
function workerRow(name, role, detail, opts){
|
||||
opts = opts || {};
|
||||
|
||||
@ -3369,134 +3369,30 @@ function addBigMeter(parent,label,val,desc){
|
||||
d.appendChild(lb);d.appendChild(row);d.appendChild(ds);parent.appendChild(d);
|
||||
}
|
||||
|
||||
// First-name → gender hint for face-pool selection. Built from the
|
||||
// most common 200 US given names. Lookup is best-effort — undefined
|
||||
// returns means "no hint, draw from full pool." Don't surface this
|
||||
// anywhere user-visible; it's purely a face-pool selector.
|
||||
var FEMALE_NAMES = new Set(['Mary','Patricia','Jennifer','Linda','Elizabeth','Barbara','Susan','Jessica','Sarah','Karen','Lisa','Nancy','Betty','Sandra','Margaret','Ashley','Kimberly','Emily','Donna','Michelle','Carol','Amanda','Melissa','Deborah','Stephanie','Dorothy','Rebecca','Sharon','Laura','Cynthia','Amy','Kathleen','Angela','Shirley','Brenda','Emma','Anna','Pamela','Nicole','Samantha','Katherine','Christine','Helen','Debra','Rachel','Carolyn','Janet','Maria','Catherine','Heather','Diane','Olivia','Julie','Joyce','Victoria','Ruth','Virginia','Lauren','Kelly','Christina','Joan','Evelyn','Judith','Andrea','Hannah','Megan','Cheryl','Jacqueline','Martha','Madison','Teresa','Gloria','Sara','Janice','Ann','Kathryn','Abigail','Sophia','Frances','Jean','Alice','Judy','Isabella','Julia','Grace','Amber','Denise','Danielle','Marilyn','Beverly','Charlotte','Natalie','Theresa','Diana','Brittany','Doris','Kayla','Alexis','Lori','Marie','Carmen','Aisha','Rosa','Kim','Mia','Audrey','Erin','Tina','Vanessa','Tara','Wendy','Tanya','Maya','Crystal','Yvonne','Kara','Shannon','Brianna','Faith','Caroline','Carla','Tracey','Tracy','Rita','Dawn','Tiffany','Stacy','Stacey','Gina','Bonnie','Tammy','Joanne','Jamie','Tonya','Alyssa','Ariana','Elena','Ellie','Erica','Erika','Felicia','Holly','Jenna','Jenny','Krista','Kristen','Kristin','Krystal','Lana','Leah','Lucy','Mallory','Melinda','Meredith','Misty','Monica','Mya','Naomi','Paige','Patrice','Paula','Renee','Rhonda','Robin','Roxanne','Sadie','Selena','Shari','Shauna','Sierra','Skylar','Sonia','Stella','Tamara','Taryn','Trina','Veronica','Vivian','Whitney','Yolanda','Zoe','Lakeisha','Latoya','Tasha',
|
||||
// Hispanic female
|
||||
'Esperanza','Luz','Lucia','Camila','Valentina','Mariana','Catalina','Cristina','Daniela','Gabriela','Ximena','Adriana','Beatriz','Pilar','Consuelo','Dolores','Mercedes','Marisol','Guadalupe','Lupita','Inez','Itzel','Yesenia','Monserrat','Renata','Alejandra','Alma','Belen','Blanca','Esmeralda','Imelda','Lourdes','Magdalena','Olga','Refugio','Rocio','Susana','Anita','Fatima',
|
||||
// South Asian female
|
||||
'Priya','Anjali','Neha','Kavya','Pooja','Divya','Meera','Lakshmi','Rani','Asha','Saanvi','Aanya','Aaradhya','Shreya','Riya','Tanvi','Ishita','Shivani','Padma','Sita','Geeta','Rekha','Amira',
|
||||
// East Asian female
|
||||
'Mei','Sakura','Aiko','Sora','Chiyo','Hana','Eun','Xiu','Lan','Hua','Min','Xin','Ying','Zhen','Yan',
|
||||
// Black female (additional)
|
||||
'Imani','Keisha','Lakisha','Kenya','Tamika','Latanya','Latrice','Aaliyah','Kiara','Janelle','Jasmine','Tanisha','Maliyah','Imari','Nia','Zuri','Talia','Jada','Ebony','Dominique',
|
||||
// Middle Eastern female
|
||||
'Layla','Yasmin','Yara','Nadia','Zainab','Rania','Samira','Mariam','Salma','Dunia','Iman','Lina','Mona','Noor','Rana','Sabrina','Soha','Zara'
|
||||
]);
|
||||
var MALE_NAMES = new Set(['James','Robert','John','Michael','David','William','Richard','Joseph','Thomas','Charles','Christopher','Daniel','Matthew','Anthony','Mark','Donald','Steven','Paul','Andrew','Joshua','Kenneth','Kevin','Brian','George','Edward','Ronald','Timothy','Jason','Jeffrey','Ryan','Jacob','Gary','Nicholas','Eric','Jonathan','Stephen','Larry','Justin','Scott','Brandon','Benjamin','Samuel','Gregory','Frank','Alexander','Raymond','Patrick','Jack','Dennis','Jerry','Tyler','Aaron','Jose','Adam','Henry','Nathan','Douglas','Zachary','Peter','Kyle','Walter','Ethan','Jeremy','Harold','Keith','Christian','Roger','Noah','Gerald','Carl','Terry','Sean','Austin','Arthur','Lawrence','Jesse','Dylan','Bryan','Joe','Jordan','Billy','Bruce','Albert','Willie','Gabriel','Logan','Alan','Juan','Wayne','Roy','Ralph','Randy','Eugene','Vincent','Russell','Elijah','Louis','Bobby','Philip','Johnny','Marcus','Antonio','Carlos','Diego','Hector','Jorge','Julio','Manuel','Miguel','Pedro','Raul','Ricardo','Roberto','Sergio','Victor','Jamal','Xavier','DeShawn','Dwayne','Jermaine','Malik','Tyrone','Devon','Andre','Anwar','Brent','Calvin','Casey','Cody','Cole','Cory','Curt','Dale','Damon','Darius','Darrell','Dean','Derek','Donnie','Drew','Earl','Eddie','Floyd','Glenn','Greg','Howard','Ivan','Jared','Jay','Jeff','Joel','Johnnie','Lance','Lee','Leonard','Lloyd','Mario','Martin','Mason','Maurice','Max','Mitchell','Morgan','Nick','Norman','Oliver','Owen','Pete','Quincy','Rafael','Reggie','Rex','Ricky','Rod','Russ','Salvatore','Shane','Shaun','Stanley','Steve','Theodore','Todd','Travis','Trevor','Troy','Wade','Warren','Wesley',
|
||||
// Hispanic male
|
||||
'Alejandro','Andres','Mateo','Santiago','Sebastian','Emilio','Tomas','Joaquin','Ignacio','Salvador','Cesar','Arturo','Armando','Hugo','Marco','Felipe','Gerardo','Jaime','Leonardo','Luis','Pablo','Ramon','Reynaldo','Vincente','Javier','Esteban','Eduardo','Fernando','Humberto','Ernestino','Cristian','Hernan',
|
||||
// South Asian male
|
||||
'Raj','Anil','Rohan','Vikram','Arjun','Sanjay','Ravi','Krishna','Pradeep','Sunil','Amit','Deepak','Ashok','Manoj','Rahul','Vijay','Suresh','Naveen','Anand','Nikhil','Aditya','Karan','Rajesh','Ramesh','Kishore','Mohan','Ajay','Aarav','Ishaan',
|
||||
// East Asian male
|
||||
'Wei','Yi','Jin','Hiroshi','Akira','Kenji','Haruto','Hyun','Yoon','Kai','Long','Hong','Hao','Tao','Bao','Cheng','Feng','Qiang','Jian','Dong','Bin','Lei','Hui','Yu','Yuan',
|
||||
// Black male (additional)
|
||||
'Demetrius','Tyrese','Trevon','Kareem','DaQuan','Tyrell','Kwame','Khalil','Rashid','Terrell','Chauncey','Cedric','Imari','Jalen','Jaylen',
|
||||
// Middle Eastern male
|
||||
'Omar','Khalid','Hassan','Hussein','Ahmed','Mohamed','Mohammed','Ali','Karim','Yusuf','Ibrahim','Mahmoud','Saif','Bilal','Faisal','Hamza','Imran','Sami','Wael','Yasin','Zaid'
|
||||
]);
|
||||
function guessGenderFromFirstName(name){
|
||||
if(!name) return null;
|
||||
var clean = name.replace(/[^A-Za-z]/g,'');
|
||||
if(!clean) return null;
|
||||
// Title-case
|
||||
var c = clean[0].toUpperCase() + clean.slice(1).toLowerCase();
|
||||
if(FEMALE_NAMES.has(c)) return 'woman';
|
||||
if(MALE_NAMES.has(c)) return 'man';
|
||||
return null;
|
||||
}
|
||||
|
||||
// First-name → ethnicity hint. The synthetic-data generator built
|
||||
// workers_500k from a multi-cultural name pool (Raj, DeShawn, Jamal,
|
||||
// Mei, Wei, Carmen, Esperanza, Aisha, etc.). The hint is used ONLY
|
||||
// to bias face-pool selection toward visually-aligned StyleGAN faces;
|
||||
// it never surfaces in any worker-facing label or report. Buckets
|
||||
// match common deepface "race" categories so the pool tags align
|
||||
// when deepface is later run over the headshot pool.
|
||||
var NAMES_SOUTH_ASIAN = new Set(['Raj','Anil','Rohan','Vikram','Arjun','Sanjay','Ravi','Krishna','Pradeep','Sunil','Amit','Deepak','Ashok','Manoj','Rahul','Vijay','Suresh','Naveen','Anand','Nikhil','Aditya','Karan','Rajesh','Ramesh','Kishore','Mohan','Ajay','Priya','Anjali','Neha','Kavya','Pooja','Divya','Meera','Lakshmi','Rani','Asha','Saanvi','Aanya','Aaradhya','Shreya','Riya','Tanvi','Ishita','Aarav','Ishaan','Shivani','Padma','Sita','Geeta','Rekha']);
|
||||
var NAMES_EAST_ASIAN = new Set(['Wei','Mei','Yi','Jin','Chen','Lin','Liu','Wang','Zhang','Yang','Wu','Zhao','Sun','Hiroshi','Yuki','Akira','Kenji','Sakura','Aiko','Haruto','Sora','Chiyo','Hana','Hyun','Eun','Yoon','Kai','Long','Hong','Xiu','Lan','Hua','Hao','Tao','Bao','Cheng','Feng','Qiang','Jian','Dong','Bin','Min','Lei','Hui','Yu','Xin','Ying','Zhen','Yuan','Yan']);
|
||||
var NAMES_HISPANIC = new Set(['Carmen','Carlos','Maria','Diego','Hector','Jorge','Julio','Manuel','Miguel','Pedro','Raul','Ricardo','Roberto','Sergio','Antonio','Esperanza','Luz','Sofia','Lucia','Isabella','Camila','Valentina','Mariana','Elena','Rosa','Catalina','Esteban','Fernando','Eduardo','Javier','Alejandro','Andres','Mateo','Santiago','Sebastian','Emilio','Tomas','Cristina','Daniela','Gabriela','Ximena','Adriana','Beatriz','Pilar','Consuelo','Dolores','Mercedes','Xavier','Marisol','Guadalupe','Lupita','Inez','Itzel','Yolanda','Yesenia','Monserrat','Renata','Ximena','Joaquin','Ignacio','Rafael','Salvador','Cesar','Arturo','Armando','Hugo','Marco','Alejandra','Alma','Belen','Blanca','Esmeralda','Fatima','Gloria','Imelda','Lourdes','Magdalena','Olga','Paula','Refugio','Rocio','Susana','Teresa','Veronica','Anita','Ernestino','Felipe','Gerardo','Humberto','Jaime','Leonardo','Luis','Pablo','Ramon','Reynaldo','Vincente']);
|
||||
var NAMES_BLACK = new Set(['DeShawn','Jamal','Aisha','Latoya','Tyrone','Malik','Imani','Keisha','Tariq','Lakisha','Kenya','Tamika','Shaquille','Andre','Marcus','Demetrius','Jermaine','Reggie','Tyrese','Darius','Trevon','Kareem','Damon','Jalen','Jaylen','Dwayne','DaQuan','Latanya','Latrice','Aaliyah','Kiara','Janelle','Jasmine','Tanisha','Yolanda','Maurice','Tyrell','Kwame','Khalil','Rashid','Terrell','Chauncey','Cedric','Maliyah','Imari','Nia','Zuri','Talia','Jada','Ebony','Dominique']);
|
||||
var NAMES_MIDDLE_EASTERN = new Set(['Layla','Omar','Khalid','Fatima','Yasmin','Hassan','Hussein','Ahmed','Mohamed','Mohammed','Ali','Karim','Yusuf','Yara','Nadia','Zainab','Rania','Samira','Mariam','Salma','Ibrahim','Mahmoud','Saif','Anwar','Bilal','Faisal','Hamza','Imran','Jamal','Rashid','Sami','Tariq','Wael','Yasin','Zaid','Amira','Dunia','Iman','Lina','Mona','Noor','Rana','Sabrina','Soha','Yara','Zara']);
|
||||
// Surname dictionaries — surname is more diagnostic than first name
|
||||
// for hispanic and asian. Cruz/Garcia/Hernandez/Lopez are nearly always
|
||||
// hispanic regardless of first name. Patel/Singh/Kumar are South Asian.
|
||||
// Chen/Wang/Liu/Nguyen are East Asian. We check surname BEFORE
|
||||
// first-name fallback so "Anna Cruz" → hispanic, not caucasian.
|
||||
var SURNAMES_HISPANIC = new Set(['Garcia','Rodriguez','Martinez','Hernandez','Lopez','Gonzalez','Perez','Sanchez','Ramirez','Torres','Flores','Rivera','Gomez','Diaz','Reyes','Cruz','Morales','Ortiz','Gutierrez','Chavez','Ramos','Ruiz','Alvarez','Mendoza','Vasquez','Castillo','Jimenez','Moreno','Romero','Herrera','Medina','Aguilar','Vargas','Castro','Fernandez','Guzman','Munoz','Salazar','Ortega','Delgado','Estrada','Ayala','Pena','Cabrera','Alvarado','Espinoza','Padilla','Cardenas','Cortes','Cortez','Ibarra','Vega','Soto','Lara','Navarro','Campos','Acosta','Rios','Marquez','Velasquez','Velazquez','Sandoval','Maldonado','Solis','Rojas','Pacheco','Mejia','Beltran','Santiago','Cervantes','Lozano','Carrillo','Galvan','Trevino','Galvez','Santana','Galvan','Robles','Valencia','Carrasco','Tapia','Lugo','Barajas','Bautista','Quintero','Salinas','Avila','Macias','Velasco','Gallegos','Calderon']);
|
||||
var SURNAMES_SOUTH_ASIAN = new Set(['Patel','Singh','Kumar','Sharma','Gupta','Shah','Khan','Mehta','Desai','Joshi','Reddy','Nair','Iyer','Verma','Agarwal','Kapoor','Chopra','Malhotra','Bhatt','Bhattacharya','Banerjee','Chatterjee','Mukherjee','Das','Sen','Bose','Roy','Saha','Sinha','Trivedi','Pandey','Mishra','Tiwari','Yadav','Chauhan','Rana','Thakur','Pillai','Menon','Krishnan','Subramanian','Raman','Rao','Naidu','Nayak','Mohan','Pradhan','Acharya','Devi','Kaur','Khanna']);
|
||||
var SURNAMES_EAST_ASIAN = new Set(['Chen','Wang','Li','Liu','Yang','Huang','Zhao','Wu','Zhou','Xu','Zhu','Sun','Ma','Lin','Lee','Kim','Park','Choi','Jung','Kang','Cho','Yoon','Han','Lim','Oh','Nakamura','Tanaka','Suzuki','Yamamoto','Sato','Watanabe','Takahashi','Kobayashi','Yoshida','Saito','Nguyen','Tran','Le','Pham','Hoang','Phan','Vu','Vo','Dang','Bui','Do','Ho','Ngo','Duong','Truong','Lam','Trinh','Mai','Cao','Lam','Wong','Tang','Tan','Cheng','Lau','Leung','Ng','Cheung','Yu','Yip','Yam','Lo','Hsu','Tsai','Hsieh','Lin']);
|
||||
var SURNAMES_MIDDLE_EASTERN = new Set(['Khan','Ahmed','Hussein','Hassan','Ali','Mahmoud','Mohamed','Mohammed','Saleh','Aziz','Karim','Hamad','Najjar','Haddad','Khoury','Mansour','Hakim','Zaman','Rahman','Iqbal','Malik','Sheikh','Siddiqui','Qureshi','Abbasi','Bukhari','Naqvi','Tahir','Anwar','Aslam','Saeed','Rizvi','Farooqi']);
|
||||
var SURNAMES_BLACK = new Set(['Washington','Jefferson','Booker','Tubman','Robinson','Jackson','Williams','Brown','Davis','Smith','Johnson','Thomas','Lewis','Walker','Wright','Edwards','Carter','Mitchell','Roberts','Phillips','Bell','Coleman','Patterson','Graham','Bailey','Reed','Cook','Morgan','Bryant','Russell','Hayes','Howard','Ward','Foster','Long','Hill','Murphy','Rivers','Banks','Boyd','Glover','Harper','Jenkins','Wallace','Mason','Spencer','Crawford','Greene','Holmes','Stewart','Pierce','Hardy','Sims','Sutton','Wells','Burke','Hines','Hudson','Mosley','Dawson','Mathis','Lyons','Newton','Watts','Whitaker','Wilkerson']);
|
||||
|
||||
function guessEthnicityFromName(firstName, lastName){
|
||||
// Try surname FIRST — it's the stronger signal for hispanic/asian
|
||||
// identity ("Anna Cruz" → hispanic via surname). Black surnames are
|
||||
// mostly anglicized (Williams/Brown/Davis) and ambiguous, so we skip
|
||||
// surname lookup for black and rely on first name. Caucasian is the
|
||||
// implicit default — never explicitly tagged.
|
||||
if(lastName){
|
||||
var s = lastName.replace(/[^A-Za-z]/g,'');
|
||||
if(s){
|
||||
var sc = s[0].toUpperCase() + s.slice(1).toLowerCase();
|
||||
if(SURNAMES_HISPANIC.has(sc)) return 'hispanic';
|
||||
if(SURNAMES_MIDDLE_EASTERN.has(sc)) return 'middle_eastern';
|
||||
if(SURNAMES_SOUTH_ASIAN.has(sc)) return 'south_asian';
|
||||
if(SURNAMES_EAST_ASIAN.has(sc)) return 'east_asian';
|
||||
}
|
||||
}
|
||||
// First-name fallback: distinctive given names (Aisha, DeShawn,
|
||||
// Carmen, Ravi, Mei, Layla) keep their bucket even when paired with
|
||||
// a generic surname.
|
||||
if(firstName){
|
||||
var clean = firstName.replace(/[^A-Za-z]/g,'');
|
||||
if(clean){
|
||||
var c = clean[0].toUpperCase() + clean.slice(1).toLowerCase();
|
||||
if(NAMES_MIDDLE_EASTERN.has(c)) return 'middle_eastern';
|
||||
if(NAMES_BLACK.has(c)) return 'black';
|
||||
if(NAMES_HISPANIC.has(c)) return 'hispanic';
|
||||
if(NAMES_SOUTH_ASIAN.has(c)) return 'south_asian';
|
||||
if(NAMES_EAST_ASIAN.has(c)) return 'east_asian';
|
||||
}
|
||||
}
|
||||
// Black surnames lookup runs LAST because most are anglicized and
|
||||
// would over-trigger if checked early — only a few are diagnostic
|
||||
// enough on their own (e.g., when first name is also generic).
|
||||
if(lastName){
|
||||
var s2 = lastName.replace(/[^A-Za-z]/g,'');
|
||||
if(s2){
|
||||
var sc2 = s2[0].toUpperCase() + s2.slice(1).toLowerCase();
|
||||
if(SURNAMES_BLACK.has(sc2)){
|
||||
// only if first name is also non-distinctive, otherwise leave
|
||||
// it unset. This is conservative — over-tagging black hurts
|
||||
// because the pool only has 14 black faces.
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'caucasian';
|
||||
}
|
||||
// Back-compat: existing callers pass only the full name as one string.
|
||||
function guessEthnicityFromFirstName(name){
|
||||
if(!name) return 'caucasian';
|
||||
var parts = String(name).trim().split(/\s+/);
|
||||
var first = parts[0] || '';
|
||||
var last = parts.length > 1 ? parts[parts.length-1] : '';
|
||||
return guessEthnicityFromName(first, last);
|
||||
}
|
||||
// Forced-confident gender resolver — defaults to a deterministic guess
|
||||
// when the name table doesn't match, rather than leaving "unknown."
|
||||
// We're authoring the synthetic data; we own the confidence call.
|
||||
function genderFor(name){
|
||||
var g = guessGenderFromFirstName(name);
|
||||
if(g) return g;
|
||||
if(!name) return 'man';
|
||||
// hash-based fallback so unknown names still spread roughly 50/50
|
||||
var s = String(name);
|
||||
var h = 0; for (var i=0;i<s.length;i++) h = (h*31 + s.charCodeAt(i))|0;
|
||||
return (Math.abs(h) & 1) ? 'man' : 'woman';
|
||||
}
|
||||
// Name → ethnicity / gender inference — REMOVED 2026-05-03 per Phase 1.6
|
||||
// BIPA gates (docs/PHASE_1_6_BIPA_GATES.md, Gate 4) and the audit-trail
|
||||
// PRD's protected-attribute exclusion rule (docs/AUDIT_TRAIL_PRD.md §4).
|
||||
//
|
||||
// What was here: FEMALE_NAMES / MALE_NAMES / NAMES_HISPANIC / NAMES_BLACK /
|
||||
// NAMES_SOUTH_ASIAN / NAMES_EAST_ASIAN / NAMES_MIDDLE_EASTERN lookup sets
|
||||
// plus parallel SURNAMES_* sets, plus guessGenderFromFirstName(),
|
||||
// guessEthnicityFromName(), guessEthnicityFromFirstName(), and
|
||||
// genderFor(). Used historically to bias synthetic-face-pool bucketing.
|
||||
//
|
||||
// Why removed: hard-coded inferred-attribute classification from candidate
|
||||
// names is (1) a Title VII / IL Human Rights Act discriminatory feature
|
||||
// engineering risk, and (2) when combined with deepface-extracted
|
||||
// classifications (per Phase 1.5 walk), forms the "biometric information
|
||||
// derived from a biometric identifier" pattern under BIPA's broad reading.
|
||||
// Removing both forecloses both arguments.
|
||||
//
|
||||
// Replacement: face-pool routing for synthetic faces uses deterministic
|
||||
// hash of candidate_id (in mcp-server/index.ts /headshots/ routes), no
|
||||
// demographic inference. Real-photo intake requires the consent gate
|
||||
// (Phase 1.6 Gate 3) and is NOT served by this UI surface.
|
||||
//
|
||||
// Do NOT re-introduce. The Phase 1.6 unit test asserts these symbols
|
||||
// stay absent from this file.
|
||||
|
||||
// Role classification — sober, no illustrations. Maps a role string
|
||||
// to a short uppercase label and a "band" used as a left-edge color
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user