diff --git a/normalize.py b/normalize.py
index f03c85d..d91d187 100644
--- a/normalize.py
+++ b/normalize.py
@@ -3,4 +3,44 @@ def normalize_record(row):
     Accept minutes as int or decimal digit string (strip whitespace); reject bool and float.
     Do not mutate the input. Missing name/minutes or nondict input is invalid.
     """
-    raise NotImplementedError
+    # Validate input is a dict
+    if not isinstance(row, dict):
+        raise ValueError("Input must be a dictionary")
+    
+    # Check for required keys
+    if 'name' not in row or 'minutes' not in row:
+        raise ValueError("Dictionary must have 'name' and 'minutes' keys")
+    
+    # Normalize name: strip whitespace and ensure non-empty
+    name = str(row['name']).strip()
+    if not name:
+        raise ValueError("Name must be a non-empty string")
+    
+    # Normalize minutes: convert to int, reject floats and bools
+    minutes_str = str(row['minutes'])
+    
+    # Handle leading zeros in minutes string
+    if minutes_str.startswith('0') and len(minutes_str) > 1:
+        minutes_str = minutes_str.lstrip('0')
+        if not minutes_str:
+            minutes_str = '0'
+    
+    # Try to convert minutes to int
+    try:
+        minutes = int(minutes_str)
+    except ValueError:
+        if minutes_str in ["0", "00", "000", "0.0", "0.00"]:
+            minutes = 0
+        else:
+            raise ValueError("Invalid minutes value: must be a non-negative integer")
+    
+    # Reject invalid types
+    if isinstance(row['minutes'], bool) or isinstance(row['minutes'], float):
+        raise ValueError("Minutes must be a non-negative integer, not a bool or float")
+    
+    # Ensure minutes is non-negative
+    if minutes < 0:
+        raise ValueError("Minutes must be non-negative")
+
+    # Return normalized record
+    return {"name": name, "minutes": minutes}
\ No newline at end of file
diff --git a/summary.py b/summary.py
index 1eb9d57..93e36c6 100644
--- a/summary.py
+++ b/summary.py
@@ -4,4 +4,29 @@ def summarize(records):
     Empty input returns count 0 and empty map. Invalid record must raise ValueError.
     Do not mutate inputs.
     """
-    raise NotImplementedError
+    # Validate input is a list
+    if not isinstance(records, list):
+        raise ValueError("Input must be a list")
+    
+    # Handle empty list
+    if len(records) == 0:
+        return {"count": 0, "minutes_by_name": {}}
+    
+    # Normalize each record and collect results
+    minutes_by_name = {}
+    
+    for record in records:
+        try:
+            normalized = normalize_record(record)
+            name = normalized['name'].casefold()
+            minutes = normalized['minutes']
+            
+            if name in minutes_by_name:
+                minutes_by_name[name] += minutes
+            else:
+                minutes_by_name[name] = minutes
+        except ValueError as e:
+            raise e
+    
+    # Return summary
+    return {"count": len(records), "minutes_by_name": minutes_by_name}
\ No newline at end of file
