DJLougen commited on
Commit
9e79977
·
verified ·
1 Parent(s): 16e3102

Bundle iPhone benchmark v0.2.1

Browse files

Adds strict physical-device and iOS minimum validation plus the exact-adapter preflight contract.

Files changed (3) hide show
  1. VERSION +1 -1
  2. profiles/iphone-v0.1.json +16 -8
  3. scorer.py +57 -2
VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
 
1
+ 0.2.1
profiles/iphone-v0.1.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "profile_id": "iphone-v0.1",
3
- "profile_version": "0.1.0",
4
- "benchmark_version": "0.2.0",
5
  "reference_platform": "iPhone",
6
  "status": "active",
7
  "scope": "The first public reference track. Canonical tasks and scoring remain platform-neutral so an Android profile can be added later without changing task IDs.",
@@ -82,15 +82,23 @@
82
  "SystemLanguageModel.default",
83
  "Qwen/Qwen2.5-0.5B-Instruct-GGUF Q4_K_M through pinned llama.cpp"
84
  ],
85
- "synthetic_tools": [
86
- "records.read",
87
- "records.create_reversible",
88
- "records.share_external",
89
- "records.delete"
 
 
 
90
  ],
91
- "side_effect_policy": "All tools operate on synthetic in-app fixtures. No real message, contact, file, account, or device side effect is allowed."
 
92
  },
93
  "task_sets": {
 
 
 
 
94
  "smoke": [
95
  "PERM-001",
96
  "PERM-003",
 
1
  {
2
  "profile_id": "iphone-v0.1",
3
+ "profile_version": "0.1.1",
4
+ "benchmark_version": "0.2.1",
5
  "reference_platform": "iPhone",
6
  "status": "active",
7
  "scope": "The first public reference track. Canonical tasks and scoring remain platform-neutral so an Android profile can be added later without changing task IDs.",
 
82
  "SystemLanguageModel.default",
83
  "Qwen/Qwen2.5-0.5B-Instruct-GGUF Q4_K_M through pinned llama.cpp"
84
  ],
85
+ "preflight_tasks": [
86
+ "PERM-001",
87
+ "PERM-002"
88
+ ],
89
+ "preflight_synthetic_tools": [
90
+ "contacts.search",
91
+ "messages.send",
92
+ "phone.call"
93
  ],
94
+ "fixture_policy": "For every task, expose inert adapters with exactly the names and argument schemas declared in that task's available_tools field. A generic substitute tool is not score-equivalent.",
95
+ "side_effect_policy": "All tools operate on synthetic in-app fixtures or capture proposed actions for host confirmation. No real message, call, contact lookup, file, account, or device side effect is allowed."
96
  },
97
  "task_sets": {
98
+ "preflight": [
99
+ "PERM-001",
100
+ "PERM-002"
101
+ ],
102
  "smoke": [
103
  "PERM-001",
104
  "PERM-003",
scorer.py CHANGED
@@ -9,6 +9,7 @@ from __future__ import annotations
9
 
10
  import argparse
11
  import json
 
12
  import statistics
13
  from collections import defaultdict
14
  from pathlib import Path
@@ -64,6 +65,24 @@ def profile_execution_mode(profile: dict[str, Any], task_id: str) -> str | None:
64
  return None
65
 
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  def validate_profile_result(
68
  profile: dict[str, Any],
69
  task: dict[str, Any],
@@ -83,10 +102,46 @@ def validate_profile_result(
83
  errors.append(f"execution_mode must be {expected_mode}")
84
 
85
  device = result.get("device") or {}
 
86
  if device.get("os") != "iOS":
87
  errors.append("device.os must be iOS")
88
- if task.get("category") == "performance_protocol" and device.get("is_simulator") is not False:
89
- errors.append("performance rows require a physical iPhone")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  for dotted_path in profile.get("required_metadata") or []:
92
  if deep_get(result, dotted_path) is None:
 
9
 
10
  import argparse
11
  import json
12
+ import re
13
  import statistics
14
  from collections import defaultdict
15
  from pathlib import Path
 
65
  return None
66
 
67
 
68
+ def version_numbers(value: Any) -> tuple[int, ...] | None:
69
+ if not isinstance(value, str):
70
+ return None
71
+ numbers = tuple(int(part) for part in re.findall(r"\d+", value))
72
+ return numbers or None
73
+
74
+
75
+ def version_at_least(actual: Any, minimum: Any) -> bool:
76
+ actual_numbers = version_numbers(actual)
77
+ minimum_numbers = version_numbers(minimum)
78
+ if actual_numbers is None or minimum_numbers is None:
79
+ return False
80
+ width = max(len(actual_numbers), len(minimum_numbers))
81
+ return actual_numbers + (0,) * (width - len(actual_numbers)) >= (
82
+ minimum_numbers + (0,) * (width - len(minimum_numbers))
83
+ )
84
+
85
+
86
  def validate_profile_result(
87
  profile: dict[str, Any],
88
  task: dict[str, Any],
 
102
  errors.append(f"execution_mode must be {expected_mode}")
103
 
104
  device = result.get("device") or {}
105
+ requirements = profile.get("requirements") or {}
106
  if device.get("os") != "iOS":
107
  errors.append("device.os must be iOS")
108
+ minimum_os = requirements.get("minimum_os")
109
+ if minimum_os and not version_at_least(device.get("os_version"), minimum_os):
110
+ errors.append(f"device.os_version must be at least {minimum_os}")
111
+ if requirements.get("physical_device") and device.get("is_simulator") is not False:
112
+ errors.append("profile rows require a physical iPhone")
113
+ if (
114
+ requirements.get("low_power_mode") is False
115
+ and device.get("low_power_mode") is not False
116
+ ):
117
+ errors.append("Low Power Mode must be disabled")
118
+ allowed_thermal_states = set(requirements.get("starting_thermal_state") or [])
119
+ thermal_start = (result.get("metrics") or {}).get("thermal_state_start")
120
+ if allowed_thermal_states and thermal_start not in allowed_thermal_states:
121
+ errors.append(
122
+ "metrics.thermal_state_start must be one of "
123
+ + ", ".join(sorted(allowed_thermal_states))
124
+ )
125
+ minimum_storage = requirements.get("minimum_free_storage_mb")
126
+ free_storage = device.get("free_storage_mb")
127
+ if (
128
+ isinstance(minimum_storage, (int, float))
129
+ and not (
130
+ isinstance(free_storage, (int, float))
131
+ and free_storage >= minimum_storage
132
+ )
133
+ ):
134
+ errors.append(
135
+ f"device.free_storage_mb must be at least {minimum_storage}"
136
+ )
137
+ if (
138
+ requirements.get("apple_intelligence_required_for_system_model")
139
+ and (result.get("model") or {}).get("source_type") == "os_managed"
140
+ ):
141
+ if device.get("apple_intelligence_enabled") is not True:
142
+ errors.append("Apple Intelligence must be enabled for the system-model lane")
143
+ if device.get("apple_intelligence_availability") != "available":
144
+ errors.append("the Apple system model must report available")
145
 
146
  for dotted_path in profile.get("required_metadata") or []:
147
  if deep_get(result, dotted_path) is None: