D2 component 3b: parse a human-filled gold artifact (see
Foresight.Evals.Labeling.GoldSet.to_artifact/2) into validated, human-sourced label
attrs ready for Foresight.Schemas.LabeledPair.changeset/2.
Ungraded pairs (blank "grade") are skipped and counted; malformed pairs (grade outside
0..3, non-numeric grade, unknown split) are collected under :errors with their
pair_id rather than silently dropped, so a labeling pass reports exactly what it took
and what it rejected. Pure: no DB.
Summary
Types
@type result() :: %{ labels: [map()], errors: [%{pair_id: String.t(), reason: atom()}], skipped: non_neg_integer() }