Validate a list of record dicts against rules — a mapping of field -> constraint, where a constraint can carry "min", "max", and/or "in" (an allowed set). The records come from a loosely typed source, so a numeric field may hold a string, a bool, or NaN. Check each field in this order:
01Missing — absent, None, or a float NaN → "<field>:missing".
02Type — if the constraint has min or max, the value must be a real number: an int or float, and not a bool (True is not 1 here). Anything else — including a numeric-looking string like "42" — is "<field>:type". Never coerce, and never raise.
03Value — below min → "<field>:below_min", above max → "<field>:above_max" (both bounds inclusive); not in the "in" set → "<field>:enum".
A field that fails step 1 or 2 gets only that one error — none of its later checks run. A falsy value like 0 is present, not missing. A record can break several fields — report all of them.
Return [(index, sorted_errors), ...] for invalid records only, in input order.
What the tests check
4 on Run · 5 on Submit01flags range and enum violations; bounds are inclusive; 0 is present
02a string in a numeric field is a :type error, not a crash and not a coerced number
03bool is not a number for min/max — True/False get only :type
04NaN counts as missing; ints and floats are both numbers
Submit runs these and one more check you don’t see, so code written for the visible tests alone can still miss.