Skip to content

profile()'s zero-detected-dimensions case scores overall_score=0/grade='F', indistinguishable from real failure #444

Description

@yakew7

Where: faircode/profiler.py's profile() (if dimensions: overall = ... else: overall = 0), and faircode/report.py's to_terminal/to_json.

The gap: a dataset with zero detected/kept dimensions (e.g. every demographic column force-mapped to ignore, or none present at all) gets overall_score=0, grade="F" - numerically and visually identical to a dataset that genuinely failed every fairness check. report.py's "No demographic columns detected." note exists only in to_terminal (line 55); it's never surfaced in the raw profile() dict or to_json's output.

Repro:

>>> import pandas as pd
>>> from faircode import profile
>>> df = pd.DataFrame({'sex': ['M','F']*20, 'id': range(40)})
>>> r = profile(df, overrides={'sex': 'ignore'})
>>> r['dimensions']
[]
>>> r['overall_score'], r['grade']
(0, 'F')

Nothing in this dict distinguishes "nothing was measured" from "everything failed."

Why it matters: this same profile() backs the MCP profile_dataset/compare_datasets tools and faircode profile --json/--fail-under. An agent or a CI gate sees {"overall_score": 0, "grade": "F"} and reasonably concludes severe bias, when actually nothing was assessed - a --fail-under gate would hard-fail for entirely the wrong reason, and an MCP-calling agent has no field to check for "was anything even measured here."

Suggested fix: use a distinct sentinel for the zero-dimensions case (e.g. overall_score: null/grade: None plus a "dimensions_detected": false field, or similar) instead of reusing the worst possible numeric score and letter grade, and propagate the existing terminal-only "no demographic columns detected" note into to_json's output and the MCP tool results too.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions