TwinEthosRequest access

Law

Illinois HB 3773 (IHRA AI amendment)

Illinois Department of Human Rights · Illinois (US-IL) · 2 provisions encoded · verified against the official source as of 2026-08-30.

Informational data, not legal advice. Summaries are TwinEthos's own words and rules have not been reviewed by a lawyer: check the official text before relying on any of it. A guard addresses an item; adding it is not a statement that your code meets any law.

Official text: ilga.gov.

Binding law — in force

Employers must notify employees that AI is being used in employment decisions (Illinois)

775 ILCS 5/2-102(L)(2) · official text · In force: applies since 1 Jan 2026 · Illinois (US-IL)

It is a civil rights violation under the Illinois Human Rights Act for an employer to fail to notify an employee that the employer is using AI for covered employment decisions (recruitment, hiring, promotion, renewal, training, discharge, discipline, tenure, terms/conditions). Applies whether or not the use is discriminatory. Detect an AI employment-decision path with no employee-notice mechanism. (IDHR is to set notice timing/means by rule.)

Who it applies to

  • Duty falls on: employer
  • Systems covered: automated decision
  • Sectors: employment
  • Illinois employers using AI in covered employment decisions must notify employees. Effective 2026-01-01; IDHR rulemaking pending on timing/means.

The guard to add

Notify applicants and employees, in the application flow, HR portal, or handbook they actually receive, that AI is used in each employment decision before it is applied to them.

An employee-facing notice tied to each AI-assisted employment process (resume screening, promotion ranking, performance or discipline scoring, scheduling), placed where people meet that process: application-flow copy, the careers page, the HR portal, or a handbook AI section. The pipeline that calls score_applicant or rank_employees records which notice version each person received, and checks that record before scoring so a new AI use case cannot go live for people who were never told. One generic hiring disclaimer does not cover promotion, discipline, or termination uses.

Where it goes: 1 application source code, 2 data models, 14 user-facing text.

What this provision adds:

  • Cover every covered decision where AI is used: recruitment, hiring, promotion, renewal, training, discharge, discipline, tenure, and terms or conditions of employment.
  • The notice is owed whether or not the AI use is discriminatory; IDHR is to set the notice timing and means by rule.

Example (Python HR scoring job (scikit-learn)), before:

def rank_employees(team_id):
    staff = hr.employees(team_id)
    return model.predict_proba(features(staff))[:, 1]

After:

def rank_employees(team_id):
    staff = hr.employees(team_id)
    missing = [e.id for e in staff if not hr.ai_notice_received(e.id, use='promotion_ranking')]
    if missing:
        raise NoticeMissing(f'AI-use notice not yet given to {len(missing)} employees')
    return model.predict_proba(features(staff))[:, 1]

Control: Employer uses AI in employment decisions without notifying the employee. The same guard addresses 1 item with binding law in 1 jurisdiction. Engineering guidance, not legal advice.

Rule id il-hb3773.ai-use-employee-notice · review status: primary source derived

Binding law — in force

Illinois employers must not use AI that discriminates on protected classes or uses ZIP codes as a proxy (employment decisions)

775 ILCS 5/2-102(L)(1) · official text · In force: applies since 1 Jan 2026 · Illinois (US-IL)

It is a civil rights violation for an Illinois employer to use AI that has the effect of subjecting employees/applicants to discrimination on the basis of protected classes, OR to use zip codes as a proxy for protected classes, across recruitment, hiring, promotion, renewal, training/apprenticeship, discharge, discipline, tenure, and terms/conditions of employment. Effect-based (no intent required). Detect protected/proxy attributes (esp. zip code) reaching an AI employment-decision path.

Who it applies to

  • Duty falls on: employer, deployer
  • Systems covered: consequential decision, automated decision
  • Sectors: employment
  • Employers with 1+ employee in Illinois using AI in covered employment decisions. Effect-based strict liability (intent is not a defense). Effective 2026-01-01. IDHR to adopt implementing rules.
  • Whether it applies depends on facts outside the code; a person has to decide.

The guard to add

Build decision prompts and feature sets from an allowlist of decision-relevant fields, and redact protected attributes, known proxies, and free text before the model sees them.

At the prompt builder or feature-assembly step on the consequential-decision path, construct model inputs from an explicit allowlist (FEATURE_ALLOWLIST, APPROVED_FEATURES) instead of passing the whole person record or f-string interpolating its fields. Protected attributes (race, sex, religion, age, disability) and proxies (ZIP or postal code, surname, school, census tract) stay out unless a documented justification and a bias test exist, and free text (cover letters, notes, transcripts) goes through redaction (redact_pii, strip_protected_attributes) first. Log the features used and the model output per decision, and run disparity tests on outcomes; human review lowers the risk but does not replace the allowlist.

Where it goes: 1 application source code, 2 data models, 7 prompt construction, 13 tests and evals.

What this provision adds:

  • Do not use ZIP codes as a proxy for protected classes anywhere on an AI employment-decision path; the test is effect-based, so lack of intent is no defense.

Example (Python + OpenAI SDK), before:

prompt = f"Applicant {a.last_name}, age {a.age}, zip {a.zip_code}.\nNotes: {a.applicant_notes}\nApprove the loan?"
resp = client.chat.completions.create(model=MODEL, messages=[{'role': 'user', 'content': prompt}])

After:

FEATURE_ALLOWLIST = ['income', 'debt_to_income', 'requested_amount', 'payment_history_months']

features = {k: getattr(a, k) for k in FEATURE_ALLOWLIST}
notes = strip_protected_attributes(a.applicant_notes)   # drops names, ages, places, etc.
messages = [{'role': 'system', 'content': LENDING_RUBRIC},
            {'role': 'user', 'content': json.dumps({'features': features, 'notes': notes})}]
resp = client.chat.completions.create(model=MODEL, messages=messages)
decision_log.record(a.id, features, resp.choices[0].message.content)

Control: Protected or proxy attribute reaches AI decision. The same guard addresses 4 items with binding law in 3 jurisdictions. Engineering guidance, not legal advice.

Standards that recommend the same control

Related incidents

No guardrail sits on this exact control; these incidents are cited by guardrails on related controls.

Rule id il-hb3773.proxy-discrimination-llm-decision-path · review status: primary source derived