diff --git a/app/verify/signals.py b/app/verify/signals.py index 50bf370..7e29dd9 100644 --- a/app/verify/signals.py +++ b/app/verify/signals.py @@ -77,6 +77,15 @@ def _year_of(value: Any) -> int | None: return None +# A bulk-imported record with no known day is stored as January 1st. The year on +# such a date is an approximation, not a measurement. +_PLACEHOLDER_SOC_YEAR_SLACK = 2 + + +def _is_placeholder_date(value: Any) -> bool: + return isinstance(value, str) and value[5:10] == "01-01" + + def parse_resolution(value: Any) -> tuple[int, int] | None: if not isinstance(value, str): return None @@ -209,11 +218,19 @@ def mobile_signals( # (e.g. Snapdragon 888 stored as 2022-01-01), so a mismatch usually means the # *SoC* record's date is wrong, not the device. We flag + penalize but don't # force-red the device on the strength of a second record's bad date. + # + # 92.9% of SoC records (1,954/2,104) carry a placeholder date, and their year + # is itself imprecise by up to ~2 years, so comparing years exactly against + # one measures the placeholder, not the device: it fails 5,488 otherwise-sound + # phones. Where the SoC date is a placeholder we only fail a gross mismatch; + # a real, day-precise SoC date is still compared exactly. soc = rec.get("soc") + soc_date = soc_release.get(soc) if isinstance(soc, str) else None dev_year = _year_of(rec.get("release_date")) - soc_year = _year_of(soc_release.get(soc)) if isinstance(soc, str) else None + soc_year = _year_of(soc_date) if dev_year is not None and soc_year is not None: - ok = soc_year <= dev_year + slack = _PLACEHOLDER_SOC_YEAR_SLACK if _is_placeholder_date(soc_date) else 0 + ok = soc_year <= dev_year + slack out.append(Signal("soc_not_after_device", "pass" if ok else "fail", hard=False)) else: out.append(Signal("soc_not_after_device", "na", hard=False)) diff --git a/tests/verify/test_signals.py b/tests/verify/test_signals.py index 5f74c1e..a601d6d 100644 --- a/tests/verify/test_signals.py +++ b/tests/verify/test_signals.py @@ -77,12 +77,29 @@ def test_storage_must_be_sorted_positive_unique(): def test_soc_not_after_device_is_soft(): - rec = {"soc": "chip-x", "release_date": "2020-01-01"} - soc_release = {"chip-x": "2022-01-01"} + rec = {"soc": "chip-x", "release_date": "2020-06-01"} + soc_release = {"chip-x": "2024-01-01"} s = _named(signals.mobile_signals(rec, NOW, soc_release), "soc_not_after_device") assert s.failed and not s.hard # flagged but never forces red +def test_placeholder_soc_date_gets_year_slack(): + """A "YYYY-01-01" SoC date is an approximation — 93% of the SoC set has one, + and its year runs up to ~2 years late, so a small gap is not evidence.""" + soc_release = {"chip-x": "2022-01-01"} + rec = {"soc": "chip-x", "release_date": "2020-09-01"} + s = _named(signals.mobile_signals(rec, NOW, soc_release), "soc_not_after_device") + assert s.result == "pass" + + +def test_real_soc_date_is_compared_exactly(): + """A day-precise SoC date is a measurement, so it keeps the strict check.""" + soc_release = {"chip-x": "2022-11-16"} + rec = {"soc": "chip-x", "release_date": "2021-09-01"} + s = _named(signals.mobile_signals(rec, NOW, soc_release), "soc_not_after_device") + assert s.result == "fail" + + def test_soc_process_nm_era(): rec = {"process_nm": 5.0, "release_date": "2010-01-01", "gpu_name": "x"} assert _named(signals.soc_signals(rec, NOW), "process_nm_era").result == "fail"