Add fail-closed real P formula data contract
Browse files- MANIFEST.json +81 -66
- README.md +1 -0
- contracts/aiflow_p_formula_v1.schema.json +63 -0
- reports/RESEARCH_REPORT.md +16 -0
- scripts/preflight_math_ink_06_p_formula.py +44 -0
- src/p_formula_gate06.py +186 -0
MANIFEST.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
๏ปฟ{
|
| 2 |
-
"schema": "aiflow-hf-research-snapshot-
|
| 3 |
-
"generated_at": "2026-07-
|
| 4 |
"track": "R_noncommercial_plus_rejected_P_proxy",
|
| 5 |
"product_validation": false,
|
| 6 |
"public_release": true,
|
| 7 |
"contains_raw_dataset": false,
|
| 8 |
-
"tests": "
|
| 9 |
"retracted_paths": [
|
| 10 |
"models/auxiliary/boundary_auxiliary_head.pt",
|
| 11 |
"models/auxiliary/seed17/boundary_joint_delta.pt",
|
|
@@ -28,6 +28,16 @@
|
|
| 28 |
"bytes": 6803,
|
| 29 |
"sha256": "4f842852093ca46b1942c942fd5e475ca6c19f044ba9e27b6d372f1aed56056e"
|
| 30 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
{
|
| 32 |
"path": "scripts/evaluate_crohme_tray_joint_selector.py",
|
| 33 |
"bytes": 11671,
|
|
@@ -38,16 +48,6 @@
|
|
| 38 |
"bytes": 11900,
|
| 39 |
"sha256": "f32a18c8e7d3a0ea36379293e6be88bfb509b7df99846c38149fb8458e6cc994"
|
| 40 |
},
|
| 41 |
-
{
|
| 42 |
-
"path": "reports/RESEARCH_REPORT.md",
|
| 43 |
-
"bytes": 31962,
|
| 44 |
-
"sha256": "704e9d2af5fc5ef36136a80b0f6d66cd0984c21a254ab937cd9d1cdd5603ce47"
|
| 45 |
-
},
|
| 46 |
-
{
|
| 47 |
-
"path": "reports/p_boundary_joint_seed17.json",
|
| 48 |
-
"bytes": 6920,
|
| 49 |
-
"sha256": "7af3bb995041e5ea621d3c9535f3552e264860f12a7e6145637849f5cd0220a8"
|
| 50 |
-
},
|
| 51 |
{
|
| 52 |
"path": "reports/online_casecontext_seed31.json",
|
| 53 |
"bytes": 33576,
|
|
@@ -63,6 +63,16 @@
|
|
| 63 |
"bytes": 15740,
|
| 64 |
"sha256": "27b31da71b9f39f7ded38aa1ce3694911af140d22854543d4ae2b5f9e709b479"
|
| 65 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
{
|
| 67 |
"path": "reports/p_boundary_device_stress_sharedfix_3seed.json",
|
| 68 |
"bytes": 10867,
|
|
@@ -73,11 +83,6 @@
|
|
| 73 |
"bytes": 16685,
|
| 74 |
"sha256": "9d250e5c75d4f104971551c07a702810bf94fb5b6e5e587035a624933766356e"
|
| 75 |
},
|
| 76 |
-
{
|
| 77 |
-
"path": "reports/online_casecontext_seed47.json",
|
| 78 |
-
"bytes": 33727,
|
| 79 |
-
"sha256": "c3dfd328d9ff0a55eed2cb74657ad87e5e164968fddd7fae8c8fd92e137a4557"
|
| 80 |
-
},
|
| 81 |
{
|
| 82 |
"path": "src/math_ink_06.py",
|
| 83 |
"bytes": 54708,
|
|
@@ -93,6 +98,11 @@
|
|
| 93 |
"bytes": 18055,
|
| 94 |
"sha256": "6fa378ccb7d08f605d4976b6ae08247d0b1fa3f2cb7ce00ba5d35b79c6dfbb47"
|
| 95 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
{
|
| 97 |
"path": "src/tray_joint.py",
|
| 98 |
"bytes": 19404,
|
|
@@ -108,25 +118,30 @@
|
|
| 108 |
"bytes": 13772,
|
| 109 |
"sha256": "8cc2dc1e13b56c21d53a76b9b863cdf5c8f8dd315da6eb18c1bd2b5b87c1a616"
|
| 110 |
},
|
| 111 |
-
{
|
| 112 |
-
"path": "scripts/train_math_ink_06_p_boundary_auxiliary.py",
|
| 113 |
-
"bytes": 20688,
|
| 114 |
-
"sha256": "70ca8a05dcbd48e79d812cd7ff44ee3d8479055f898143daa6d6ea7580b2973e"
|
| 115 |
-
},
|
| 116 |
{
|
| 117 |
"path": "scripts/summarize_math_ink_06_p_boundary_joint.py",
|
| 118 |
"bytes": 4580,
|
| 119 |
"sha256": "c6ce78f521232bdb7e967b0c358232a72dd3f79747f9e32eb240d9bb10c6a422"
|
| 120 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
{
|
| 122 |
"path": "scripts/export_math_ink_06_litert.py",
|
| 123 |
"bytes": 8637,
|
| 124 |
"sha256": "e96b30ded57d33d4505b065c1ac69c5ac7db43618c0eb7f3b7fb787b6fcaf1f6"
|
| 125 |
},
|
| 126 |
{
|
| 127 |
-
"path": "scripts/
|
| 128 |
-
"bytes":
|
| 129 |
-
"sha256": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
},
|
| 131 |
{
|
| 132 |
"path": "scripts/train_math_ink_06_boundary_behavior_guard.py",
|
|
@@ -138,21 +153,6 @@
|
|
| 138 |
"bytes": 9063,
|
| 139 |
"sha256": "28cfc7b9b695256cfa9199d912d1d938d402292b88e9411d42fddb3508446d3b"
|
| 140 |
},
|
| 141 |
-
{
|
| 142 |
-
"path": "scripts/sweep_math_ink_06_component_competition_guard.py",
|
| 143 |
-
"bytes": 9084,
|
| 144 |
-
"sha256": "e2dee616e2c6ebdc32281624889017685648b7076515242e04a1452d98d1c7da"
|
| 145 |
-
},
|
| 146 |
-
{
|
| 147 |
-
"path": "reports/local_baseline_overmerge_audit.json",
|
| 148 |
-
"bytes": 1237409,
|
| 149 |
-
"sha256": "33a9ccafebd559ca8b173f011e9a0a6f495d37b8fdb2693673663479d3457071"
|
| 150 |
-
},
|
| 151 |
-
{
|
| 152 |
-
"path": "exports/seed17/raster.pt2",
|
| 153 |
-
"bytes": 9465689,
|
| 154 |
-
"sha256": "419301d67bbfe7b807e1ea676a33827c749f632300392d54eaf48c701ca07512"
|
| 155 |
-
},
|
| 156 |
{
|
| 157 |
"path": "exports/seed17/online.pt2",
|
| 158 |
"bytes": 9192090,
|
|
@@ -163,6 +163,16 @@
|
|
| 163 |
"bytes": 1030,
|
| 164 |
"sha256": "48a224d03fb2e8f1c4fcb6ca3f61456521f4437b4cfc845572111cd84cb93833"
|
| 165 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
{
|
| 167 |
"path": "models/seed17/online_adapter.pt",
|
| 168 |
"bytes": 2875654,
|
|
@@ -178,11 +188,6 @@
|
|
| 178 |
"bytes": 8638290,
|
| 179 |
"sha256": "f3b0e53b50e41cf57d4881c501371b35648cf049d603984a0edf6148c2b62bd7"
|
| 180 |
},
|
| 181 |
-
{
|
| 182 |
-
"path": "assets/stroke_encoding.svg",
|
| 183 |
-
"bytes": 3882,
|
| 184 |
-
"sha256": "66bf7659c2e86fd53e6583e7c5deb8d371432469c07d4e4ca0dd165b4a81f4ed"
|
| 185 |
-
},
|
| 186 |
{
|
| 187 |
"path": "pyproject.snapshot.toml",
|
| 188 |
"bytes": 669,
|
|
@@ -198,6 +203,16 @@
|
|
| 198 |
"bytes": 2406,
|
| 199 |
"sha256": "2419245ba889772d562d524999e9d14f801e70d87ce75e38231722eb5aecd697"
|
| 200 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
{
|
| 202 |
"path": "assets/architecture.svg",
|
| 203 |
"bytes": 5695,
|
|
@@ -208,11 +223,6 @@
|
|
| 208 |
"bytes": 824191,
|
| 209 |
"sha256": "18aff472c1bdb25a519b1553364229c9869aed1f36a9d663cf88a1bc808fab8f"
|
| 210 |
},
|
| 211 |
-
{
|
| 212 |
-
"path": "README.md",
|
| 213 |
-
"bytes": 11132,
|
| 214 |
-
"sha256": "5d08c5e2735e52acb557ef6b7792f5573508508297ca8054ca5ecad2e7311d8d"
|
| 215 |
-
},
|
| 216 |
{
|
| 217 |
"path": "reports/behavior_role_seed47.json",
|
| 218 |
"bytes": 30091,
|
|
@@ -228,6 +238,16 @@
|
|
| 228 |
"bytes": 29047,
|
| 229 |
"sha256": "e2072fec1b1065777f0e9218c48d27f096b22f5545e7cc8d9962939282719561"
|
| 230 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
{
|
| 232 |
"path": "reports/local_baseline_guard_report.json",
|
| 233 |
"bytes": 24052,
|
|
@@ -238,16 +258,6 @@
|
|
| 238 |
"bytes": 22284,
|
| 239 |
"sha256": "4d3db5f71e5008381dd072f2c10aafb22e08f96e23f2a32f82a3a46abd9c70b9"
|
| 240 |
},
|
| 241 |
-
{
|
| 242 |
-
"path": "reports/boundary_behavior_guard_report.json",
|
| 243 |
-
"bytes": 72053,
|
| 244 |
-
"sha256": "f55a230a9f0892b9676c71db46e9e527862b3d8da776dc43db767ce7a0f6a5c7"
|
| 245 |
-
},
|
| 246 |
-
{
|
| 247 |
-
"path": "reports/behavior_role_3seed_summary.json",
|
| 248 |
-
"bytes": 3567,
|
| 249 |
-
"sha256": "b16049218d2d006d952f59f55642fa9f3fbfbc3cc3a730fbd7b075f507c3b251"
|
| 250 |
-
},
|
| 251 |
{
|
| 252 |
"path": "models/seed31/online_adapter.pt",
|
| 253 |
"bytes": 2875654,
|
|
@@ -263,6 +273,16 @@
|
|
| 263 |
"bytes": 8638290,
|
| 264 |
"sha256": "e3c57bc8cbbd4542cacf7ab9200a9031dcdc5ee63ffbd6ad6c9f7ef4f0a64f37"
|
| 265 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
{
|
| 267 |
"path": "models/seed47/online_adapter.pt",
|
| 268 |
"bytes": 2876038,
|
|
@@ -272,11 +292,6 @@
|
|
| 272 |
"path": "models/seed47/behavior_role_head.pt",
|
| 273 |
"bytes": 75794,
|
| 274 |
"sha256": "f28fad4e0289e3bc9400829f41aba9bbd75c43d445b7462a84aadbdbe635c10b"
|
| 275 |
-
},
|
| 276 |
-
{
|
| 277 |
-
"path": "models/seed47/base_378.pt",
|
| 278 |
-
"bytes": 8638290,
|
| 279 |
-
"sha256": "4131b21f6b00471c1c5a82aee4a2da45e599e42dc742fc1dd0dd8afb970f8939"
|
| 280 |
}
|
| 281 |
]
|
| 282 |
}
|
|
|
|
| 1 |
๏ปฟ{
|
| 2 |
+
"schema": "aiflow-hf-research-snapshot-v8",
|
| 3 |
+
"generated_at": "2026-07-23T20:04:13.5124140Z",
|
| 4 |
"track": "R_noncommercial_plus_rejected_P_proxy",
|
| 5 |
"product_validation": false,
|
| 6 |
"public_release": true,
|
| 7 |
"contains_raw_dataset": false,
|
| 8 |
+
"tests": "282 passed",
|
| 9 |
"retracted_paths": [
|
| 10 |
"models/auxiliary/boundary_auxiliary_head.pt",
|
| 11 |
"models/auxiliary/seed17/boundary_joint_delta.pt",
|
|
|
|
| 28 |
"bytes": 6803,
|
| 29 |
"sha256": "4f842852093ca46b1942c942fd5e475ca6c19f044ba9e27b6d372f1aed56056e"
|
| 30 |
},
|
| 31 |
+
{
|
| 32 |
+
"path": "reports/RESEARCH_REPORT.md",
|
| 33 |
+
"bytes": 33159,
|
| 34 |
+
"sha256": "19c06349b4316cb538a48fbe1cf5fccaaa386ca215615ae6ca53bfaefc0995df"
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"path": "scripts/evaluate_math_ink_06_p_boundary_device_stress.py",
|
| 38 |
+
"bytes": 10444,
|
| 39 |
+
"sha256": "bdd75047c4887a6e53720f1c84d224545844cdbd9b0239826a605d578b3c92a6"
|
| 40 |
+
},
|
| 41 |
{
|
| 42 |
"path": "scripts/evaluate_crohme_tray_joint_selector.py",
|
| 43 |
"bytes": 11671,
|
|
|
|
| 48 |
"bytes": 11900,
|
| 49 |
"sha256": "f32a18c8e7d3a0ea36379293e6be88bfb509b7df99846c38149fb8458e6cc994"
|
| 50 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
{
|
| 52 |
"path": "reports/online_casecontext_seed31.json",
|
| 53 |
"bytes": 33576,
|
|
|
|
| 63 |
"bytes": 15740,
|
| 64 |
"sha256": "27b31da71b9f39f7ded38aa1ce3694911af140d22854543d4ae2b5f9e709b479"
|
| 65 |
},
|
| 66 |
+
{
|
| 67 |
+
"path": "reports/online_casecontext_seed47.json",
|
| 68 |
+
"bytes": 33727,
|
| 69 |
+
"sha256": "c3dfd328d9ff0a55eed2cb74657ad87e5e164968fddd7fae8c8fd92e137a4557"
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"path": "reports/p_boundary_joint_seed17.json",
|
| 73 |
+
"bytes": 6920,
|
| 74 |
+
"sha256": "7af3bb995041e5ea621d3c9535f3552e264860f12a7e6145637849f5cd0220a8"
|
| 75 |
+
},
|
| 76 |
{
|
| 77 |
"path": "reports/p_boundary_device_stress_sharedfix_3seed.json",
|
| 78 |
"bytes": 10867,
|
|
|
|
| 83 |
"bytes": 16685,
|
| 84 |
"sha256": "9d250e5c75d4f104971551c07a702810bf94fb5b6e5e587035a624933766356e"
|
| 85 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
{
|
| 87 |
"path": "src/math_ink_06.py",
|
| 88 |
"bytes": 54708,
|
|
|
|
| 98 |
"bytes": 18055,
|
| 99 |
"sha256": "6fa378ccb7d08f605d4976b6ae08247d0b1fa3f2cb7ce00ba5d35b79c6dfbb47"
|
| 100 |
},
|
| 101 |
+
{
|
| 102 |
+
"path": "src/p_formula_gate06.py",
|
| 103 |
+
"bytes": 7910,
|
| 104 |
+
"sha256": "00c8cb3fd5b53f2d118886d7333fe75d62f2d7b7e7b161b662adbd43d1b14a7f"
|
| 105 |
+
},
|
| 106 |
{
|
| 107 |
"path": "src/tray_joint.py",
|
| 108 |
"bytes": 19404,
|
|
|
|
| 118 |
"bytes": 13772,
|
| 119 |
"sha256": "8cc2dc1e13b56c21d53a76b9b863cdf5c8f8dd315da6eb18c1bd2b5b87c1a616"
|
| 120 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
{
|
| 122 |
"path": "scripts/summarize_math_ink_06_p_boundary_joint.py",
|
| 123 |
"bytes": 4580,
|
| 124 |
"sha256": "c6ce78f521232bdb7e967b0c358232a72dd3f79747f9e32eb240d9bb10c6a422"
|
| 125 |
},
|
| 126 |
+
{
|
| 127 |
+
"path": "scripts/preflight_math_ink_06_p_formula.py",
|
| 128 |
+
"bytes": 1664,
|
| 129 |
+
"sha256": "36aeeab2f2474ce874ef932b24eb062dfc3b9e6cf3c0d59410a052a9c9835a07"
|
| 130 |
+
},
|
| 131 |
{
|
| 132 |
"path": "scripts/export_math_ink_06_litert.py",
|
| 133 |
"bytes": 8637,
|
| 134 |
"sha256": "e96b30ded57d33d4505b065c1ac69c5ac7db43618c0eb7f3b7fb787b6fcaf1f6"
|
| 135 |
},
|
| 136 |
{
|
| 137 |
+
"path": "scripts/sweep_math_ink_06_component_competition_guard.py",
|
| 138 |
+
"bytes": 9084,
|
| 139 |
+
"sha256": "e2dee616e2c6ebdc32281624889017685648b7076515242e04a1452d98d1c7da"
|
| 140 |
+
},
|
| 141 |
+
{
|
| 142 |
+
"path": "scripts/train_math_ink_06_p_boundary_auxiliary.py",
|
| 143 |
+
"bytes": 20688,
|
| 144 |
+
"sha256": "70ca8a05dcbd48e79d812cd7ff44ee3d8479055f898143daa6d6ea7580b2973e"
|
| 145 |
},
|
| 146 |
{
|
| 147 |
"path": "scripts/train_math_ink_06_boundary_behavior_guard.py",
|
|
|
|
| 153 |
"bytes": 9063,
|
| 154 |
"sha256": "28cfc7b9b695256cfa9199d912d1d938d402292b88e9411d42fddb3508446d3b"
|
| 155 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
{
|
| 157 |
"path": "exports/seed17/online.pt2",
|
| 158 |
"bytes": 9192090,
|
|
|
|
| 163 |
"bytes": 1030,
|
| 164 |
"sha256": "48a224d03fb2e8f1c4fcb6ca3f61456521f4437b4cfc845572111cd84cb93833"
|
| 165 |
},
|
| 166 |
+
{
|
| 167 |
+
"path": "contracts/aiflow_p_formula_v1.schema.json",
|
| 168 |
+
"bytes": 1903,
|
| 169 |
+
"sha256": "c78c8a612d2f24a5c09fe1aa158b365481102869c3f84b3a5510a895b416c424"
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"path": "exports/seed17/raster.pt2",
|
| 173 |
+
"bytes": 9465689,
|
| 174 |
+
"sha256": "419301d67bbfe7b807e1ea676a33827c749f632300392d54eaf48c701ca07512"
|
| 175 |
+
},
|
| 176 |
{
|
| 177 |
"path": "models/seed17/online_adapter.pt",
|
| 178 |
"bytes": 2875654,
|
|
|
|
| 188 |
"bytes": 8638290,
|
| 189 |
"sha256": "f3b0e53b50e41cf57d4881c501371b35648cf049d603984a0edf6148c2b62bd7"
|
| 190 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
{
|
| 192 |
"path": "pyproject.snapshot.toml",
|
| 193 |
"bytes": 669,
|
|
|
|
| 203 |
"bytes": 2406,
|
| 204 |
"sha256": "2419245ba889772d562d524999e9d14f801e70d87ce75e38231722eb5aecd697"
|
| 205 |
},
|
| 206 |
+
{
|
| 207 |
+
"path": "README.md",
|
| 208 |
+
"bytes": 11248,
|
| 209 |
+
"sha256": "d102514283972dbddc061848a1fb33a5d4f581dea0b43dc9eb3f4f8de46d5885"
|
| 210 |
+
},
|
| 211 |
+
{
|
| 212 |
+
"path": "assets/stroke_encoding.svg",
|
| 213 |
+
"bytes": 3882,
|
| 214 |
+
"sha256": "66bf7659c2e86fd53e6583e7c5deb8d371432469c07d4e4ca0dd165b4a81f4ed"
|
| 215 |
+
},
|
| 216 |
{
|
| 217 |
"path": "assets/architecture.svg",
|
| 218 |
"bytes": 5695,
|
|
|
|
| 223 |
"bytes": 824191,
|
| 224 |
"sha256": "18aff472c1bdb25a519b1553364229c9869aed1f36a9d663cf88a1bc808fab8f"
|
| 225 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
{
|
| 227 |
"path": "reports/behavior_role_seed47.json",
|
| 228 |
"bytes": 30091,
|
|
|
|
| 238 |
"bytes": 29047,
|
| 239 |
"sha256": "e2072fec1b1065777f0e9218c48d27f096b22f5545e7cc8d9962939282719561"
|
| 240 |
},
|
| 241 |
+
{
|
| 242 |
+
"path": "reports/boundary_behavior_guard_report.json",
|
| 243 |
+
"bytes": 72053,
|
| 244 |
+
"sha256": "f55a230a9f0892b9676c71db46e9e527862b3d8da776dc43db767ce7a0f6a5c7"
|
| 245 |
+
},
|
| 246 |
+
{
|
| 247 |
+
"path": "reports/local_baseline_overmerge_audit.json",
|
| 248 |
+
"bytes": 1237409,
|
| 249 |
+
"sha256": "33a9ccafebd559ca8b173f011e9a0a6f495d37b8fdb2693673663479d3457071"
|
| 250 |
+
},
|
| 251 |
{
|
| 252 |
"path": "reports/local_baseline_guard_report.json",
|
| 253 |
"bytes": 24052,
|
|
|
|
| 258 |
"bytes": 22284,
|
| 259 |
"sha256": "4d3db5f71e5008381dd072f2c10aafb22e08f96e23f2a32f82a3a46abd9c70b9"
|
| 260 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
{
|
| 262 |
"path": "models/seed31/online_adapter.pt",
|
| 263 |
"bytes": 2875654,
|
|
|
|
| 273 |
"bytes": 8638290,
|
| 274 |
"sha256": "e3c57bc8cbbd4542cacf7ab9200a9031dcdc5ee63ffbd6ad6c9f7ef4f0a64f37"
|
| 275 |
},
|
| 276 |
+
{
|
| 277 |
+
"path": "models/seed47/base_378.pt",
|
| 278 |
+
"bytes": 8638290,
|
| 279 |
+
"sha256": "4131b21f6b00471c1c5a82aee4a2da45e599e42dc742fc1dd0dd8afb970f8939"
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"path": "reports/behavior_role_3seed_summary.json",
|
| 283 |
+
"bytes": 3567,
|
| 284 |
+
"sha256": "b16049218d2d006d952f59f55642fa9f3fbfbc3cc3a730fbd7b075f507c3b251"
|
| 285 |
+
},
|
| 286 |
{
|
| 287 |
"path": "models/seed47/online_adapter.pt",
|
| 288 |
"bytes": 2876038,
|
|
|
|
| 292 |
"path": "models/seed47/behavior_role_head.pt",
|
| 293 |
"bytes": 75794,
|
| 294 |
"sha256": "f28fad4e0289e3bc9400829f41aba9bbd75c43d445b7462a84aadbdbe635c10b"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
}
|
| 296 |
]
|
| 297 |
}
|
README.md
CHANGED
|
@@ -247,4 +247,5 @@ PyTorch checkpoint์ joblib/pickle์ ์ ๋ขฐํ ์ ์๋ ์ถ์ฒ์์ ๋ก๋
|
|
| 247 |
- P boundary ์ ์ 3-seed: [`reports/p_boundary_joint_sharedfix_3seed_summary.json`](reports/p_boundary_joint_sharedfix_3seed_summary.json)
|
| 248 |
- ์ ์ main device stress: [`reports/p_boundary_device_stress_sharedfix_3seed.json`](reports/p_boundary_device_stress_sharedfix_3seed.json)
|
| 249 |
- Seed-17 composite export: [`exports/seed17/export_manifest.json`](exports/seed17/export_manifest.json)
|
|
|
|
| 250 |
- ํ์ผ checksum: [`MANIFEST.json`](MANIFEST.json)
|
|
|
|
| 247 |
- P boundary ์ ์ 3-seed: [`reports/p_boundary_joint_sharedfix_3seed_summary.json`](reports/p_boundary_joint_sharedfix_3seed_summary.json)
|
| 248 |
- ์ ์ main device stress: [`reports/p_boundary_device_stress_sharedfix_3seed.json`](reports/p_boundary_device_stress_sharedfix_3seed.json)
|
| 249 |
- Seed-17 composite export: [`exports/seed17/export_manifest.json`](exports/seed17/export_manifest.json)
|
| 250 |
+
- ์ค์ P formula schema: [`contracts/aiflow_p_formula_v1.schema.json`](contracts/aiflow_p_formula_v1.schema.json)
|
| 251 |
- ํ์ผ checksum: [`MANIFEST.json`](MANIFEST.json)
|
contracts/aiflow_p_formula_v1.schema.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
| 3 |
+
"$id": "https://aiflow.local/schemas/p-formula-v1.json",
|
| 4 |
+
"title": "AIFlow Math Ink 0.6 P Formula Record",
|
| 5 |
+
"type": "object",
|
| 6 |
+
"required": [
|
| 7 |
+
"formula_id",
|
| 8 |
+
"origin_id",
|
| 9 |
+
"writer_id",
|
| 10 |
+
"device_id",
|
| 11 |
+
"source_id",
|
| 12 |
+
"split",
|
| 13 |
+
"canvas_width",
|
| 14 |
+
"canvas_height",
|
| 15 |
+
"rights_track",
|
| 16 |
+
"commercial_training_allowed",
|
| 17 |
+
"symbols"
|
| 18 |
+
],
|
| 19 |
+
"properties": {
|
| 20 |
+
"formula_id": {"type": "string", "minLength": 1},
|
| 21 |
+
"origin_id": {"type": "string", "minLength": 1},
|
| 22 |
+
"writer_id": {"type": "string", "minLength": 1},
|
| 23 |
+
"device_id": {"type": "string", "minLength": 1},
|
| 24 |
+
"source_id": {"type": "string", "minLength": 1},
|
| 25 |
+
"split": {"enum": ["training", "validation", "test"]},
|
| 26 |
+
"canvas_width": {"type": "number", "exclusiveMinimum": 0},
|
| 27 |
+
"canvas_height": {"type": "number", "exclusiveMinimum": 0},
|
| 28 |
+
"rights_track": {"const": "P"},
|
| 29 |
+
"commercial_training_allowed": {"const": true},
|
| 30 |
+
"symbols": {
|
| 31 |
+
"type": "array",
|
| 32 |
+
"minItems": 1,
|
| 33 |
+
"items": {
|
| 34 |
+
"type": "object",
|
| 35 |
+
"required": ["token", "strokes"],
|
| 36 |
+
"properties": {
|
| 37 |
+
"token": {"type": "string", "minLength": 1},
|
| 38 |
+
"strokes": {
|
| 39 |
+
"type": "array",
|
| 40 |
+
"minItems": 1,
|
| 41 |
+
"items": {
|
| 42 |
+
"type": "array",
|
| 43 |
+
"minItems": 1,
|
| 44 |
+
"items": {
|
| 45 |
+
"type": "object",
|
| 46 |
+
"required": ["x", "y"],
|
| 47 |
+
"properties": {
|
| 48 |
+
"x": {"type": "number"},
|
| 49 |
+
"y": {"type": "number"},
|
| 50 |
+
"t": {"type": ["number", "null"]},
|
| 51 |
+
"pressure": {"type": ["number", "null"]}
|
| 52 |
+
},
|
| 53 |
+
"additionalProperties": true
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
},
|
| 58 |
+
"additionalProperties": true
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
},
|
| 62 |
+
"additionalProperties": true
|
| 63 |
+
}
|
reports/RESEARCH_REPORT.md
CHANGED
|
@@ -409,6 +409,19 @@ Joint delta ์์ด ์ ์ ๋ main๊ณผ ์ auxiliary head๋ง ๋์์ผ๋ก device s
|
|
| 409 |
|
| 410 |
Seed 17ยท31ยท47 ๋ชจ๋ online/raster ๊ฐ๊ฐ ๋ํ ์
๋ ฅ 76๊ฐ์์ eager ๋๋น top-1 100% ์ผ์น, ์ต๋ logit ์ ๋์ค์ฐจ 0.0์ผ๋ก strict `torch.export` gate๋ฅผ ํต๊ณผํ๋ค. Seed๋น ๋ graph ํฉ๊ณ๋ 18,657,779 bytes๋ก 25MB ์์ฐ ์์ด๋ค. ๋ค๋ง `.pt2`๋ Android LiteRT artifact๊ฐ ์๋๋ค. ๊ณต์ LiteRT Torch 0.9.1์ Linux ํ๊ฒฝ์ ์๊ตฌํ๋ฉฐ WSL ๋ณํ ํ๊ฒฝ ์ค์น ์ค WSL filesystem I/O ์ค๋ฅ๊ฐ ๋ฐ์ํด `.tflite` ๋ณํ๊ณผ runtime parity๋ ์์ง ๋ฏธ์๋ฃ๋ค.
|
| 411 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
## ์ฐ์ถ๋ฌผ
|
| 413 |
|
| 414 |
- `src/math_grid_drawer/research/behavior_context06.py`
|
|
@@ -432,9 +445,12 @@ Seed 17ยท31ยท47 ๋ชจ๋ online/raster ๊ฐ๊ฐ ๋ํ ์
๋ ฅ 76๊ฐ์์ eager ๋
|
|
| 432 |
- `scripts/summarize_math_ink_06_p_boundary_joint.py`
|
| 433 |
- `scripts/evaluate_math_ink_06_p_boundary_device_stress.py`
|
| 434 |
- `scripts/export_math_ink_06_litert.py`
|
|
|
|
| 435 |
- `scripts/analyze_crohme_lattice_failures.py`
|
| 436 |
- `tests/test_behavior_context06.py`
|
| 437 |
- `tests/test_behavior_role_head06.py`
|
|
|
|
|
|
|
| 438 |
- `research/AIFlow-MATH-INK-0.6-BEHAVIOR-CONTEXT-REPORT-20260724.md`
|
| 439 |
- `research/runs/math_ink_06_behavior_role_3seed_20260724/run_summary.json`
|
| 440 |
- `research/runs/math_ink_06_behavior_grouping_audit_20260724/report.json`
|
|
|
|
| 409 |
|
| 410 |
Seed 17ยท31ยท47 ๋ชจ๋ online/raster ๊ฐ๊ฐ ๋ํ ์
๋ ฅ 76๊ฐ์์ eager ๋๋น top-1 100% ์ผ์น, ์ต๋ logit ์ ๋์ค์ฐจ 0.0์ผ๋ก strict `torch.export` gate๋ฅผ ํต๊ณผํ๋ค. Seed๋น ๋ graph ํฉ๊ณ๋ 18,657,779 bytes๋ก 25MB ์์ฐ ์์ด๋ค. ๋ค๋ง `.pt2`๋ Android LiteRT artifact๊ฐ ์๋๋ค. ๊ณต์ LiteRT Torch 0.9.1์ Linux ํ๊ฒฝ์ ์๊ตฌํ๋ฉฐ WSL ๋ณํ ํ๊ฒฝ ์ค์น ์ค WSL filesystem I/O ์ค๋ฅ๊ฐ ๋ฐ์ํด `.tflite` ๋ณํ๊ณผ runtime parity๋ ์์ง ๋ฏธ์๋ฃ๋ค.
|
| 411 |
|
| 412 |
+
### ์ค์ P ์ฐ์์ ๋ฐ์ดํฐ ๊ณ์ฝ
|
| 413 |
+
|
| 414 |
+
์ค์ ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ๊ธฐ ์ ์ `AIFlow P Formula v1` JSON Schema์ fail-closed preflight๋ฅผ ์ถ๊ฐํ๋ค. ๊ฐ formula๋ ๋ค์ ๊ทผ๊ฑฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์ผ ํ๋ค.
|
| 415 |
+
|
| 416 |
+
- ๊ณ ์ `formula_id`, ์๋ณธ ์ถ์ ์ฉ `origin_id`
|
| 417 |
+
- ๋น์ด ์์ง ์์ `writer_id`, `device_id`, `source_id`
|
| 418 |
+
- `training|validation|test` split
|
| 419 |
+
- `rights_track=P`, `commercial_training_allowed=true`
|
| 420 |
+
- ์์ canvas ํฌ๊ธฐ
|
| 421 |
+
- token๊ณผ ์๋ณธ raw stroke๊ฐ ํฌํจ๋ ์ ๋ต symbol group
|
| 422 |
+
|
| 423 |
+
Originยทwriterยทdeviceยทsource๊ฐ ๋ ์ด์์ split์ ๋ํ๋๋ฉด ์ ํ ํ๊ฐ๋ฅผ ๊ฑฐ๋ถํ๋ค. Timestamp์ pressure๊ฐ ์๋ symbol์ ์ญ์ ํ๊ฑฐ๋ ๊ด์ธก๊ฐ์ผ๋ก ์์ฅํ์ง ์๊ณ missing slice๋ก ์ผ๋ค. ๊ฒ์ฆ๋ formula์ ์ค์ symbol group์ boundary ์์ฑ, ์ธ์ ํ ๋ symbol group ๊ฒฐํฉ์ boundary ์์ฑ์ผ๋ก ๋ง๋ ๋ค. ์ด ๊ณ์ฝ์ ์ค์ ์ฑ๋ฅ๊ฐ์ ๋ง๋ค์ง๋ ์์ง๋ง, ํฅํ P ์
๋ ฅ์ด CROHME ์ ๋ต group์ด๋ ํฉ์ฑ ๊ณ ๋ฆฝ๊ธฐํธ proxy์ ์์ด๋ ๊ฒ์ ๋ฐฉ์งํ๋ค. ์ ์ฒด ํ๊ท๋ 282๊ฐ๊ฐ ํต๊ณผํ๋ค.
|
| 424 |
+
|
| 425 |
## ์ฐ์ถ๋ฌผ
|
| 426 |
|
| 427 |
- `src/math_grid_drawer/research/behavior_context06.py`
|
|
|
|
| 445 |
- `scripts/summarize_math_ink_06_p_boundary_joint.py`
|
| 446 |
- `scripts/evaluate_math_ink_06_p_boundary_device_stress.py`
|
| 447 |
- `scripts/export_math_ink_06_litert.py`
|
| 448 |
+
- `scripts/preflight_math_ink_06_p_formula.py`
|
| 449 |
- `scripts/analyze_crohme_lattice_failures.py`
|
| 450 |
- `tests/test_behavior_context06.py`
|
| 451 |
- `tests/test_behavior_role_head06.py`
|
| 452 |
+
- `tests/test_p_formula_gate06.py`
|
| 453 |
+
- `research/contracts/aiflow_p_formula_v1.schema.json`
|
| 454 |
- `research/AIFlow-MATH-INK-0.6-BEHAVIOR-CONTEXT-REPORT-20260724.md`
|
| 455 |
- `research/runs/math_ink_06_behavior_role_3seed_20260724/run_summary.json`
|
| 456 |
- `research/runs/math_ink_06_behavior_grouping_audit_20260724/report.json`
|
scripts/preflight_math_ink_06_p_formula.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""์ค์ P ์ฐ์ ์์ JSONL์ ํ์ตยทํ๊ฐ ์ ์ fail-closed๋ก ๊ฐ์ฌํ๋ค."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import argparse
|
| 6 |
+
from datetime import datetime, timezone
|
| 7 |
+
import json
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
import sys
|
| 10 |
+
|
| 11 |
+
PROJECT_ROOT = Path(__file__).parents[1]
|
| 12 |
+
SOURCE_ROOT = PROJECT_ROOT / "src"
|
| 13 |
+
if str(SOURCE_ROOT) not in sys.path:
|
| 14 |
+
sys.path.insert(0, str(SOURCE_ROOT))
|
| 15 |
+
|
| 16 |
+
from math_grid_drawer.research.external_corpus import read_jsonl
|
| 17 |
+
from math_grid_drawer.research.p_formula_gate06 import audit_p_formula_records06
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def main() -> None:
|
| 21 |
+
"""ํ์ ๋ณ์: UTF-8 JSONLยท์ต์ source ์ยท์ถ๋ ฅ. ์๋ ์๋ฆฌ: ์ค์ P gate ์ ๊ฒฉ ์ฌ๋ถ์ ๋ชจ๋ ๋์ ์์ธ์ JSON์ผ๋ก ๋จ๊ธด๋ค."""
|
| 22 |
+
|
| 23 |
+
parser = argparse.ArgumentParser(description="Preflight real P continuous formula data")
|
| 24 |
+
parser.add_argument("--data", type=Path, required=True)
|
| 25 |
+
parser.add_argument("--minimum-independent-sources", type=int, default=2)
|
| 26 |
+
parser.add_argument("--output", type=Path, required=True)
|
| 27 |
+
args = parser.parse_args()
|
| 28 |
+
records = list(read_jsonl(args.data))
|
| 29 |
+
report = audit_p_formula_records06(
|
| 30 |
+
records, minimum_independent_sources=args.minimum_independent_sources,
|
| 31 |
+
)
|
| 32 |
+
report["generated_at"] = datetime.now(timezone.utc).isoformat()
|
| 33 |
+
report["data"] = str(args.data)
|
| 34 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 35 |
+
args.output.write_text(
|
| 36 |
+
json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8",
|
| 37 |
+
)
|
| 38 |
+
print(json.dumps(report, ensure_ascii=False, indent=2))
|
| 39 |
+
if not report["eligible_for_product_evaluation"]:
|
| 40 |
+
raise SystemExit(2)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
if __name__ == "__main__":
|
| 44 |
+
main()
|
src/p_formula_gate06.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""์ค์ P ์ฐ์ ์์์ ๊ถ๋ฆฌยท๋ถํ ยทsymbol-group ๊ณ์ฝ์ fail-closed๋ก ๊ฒ์ฌํ๋ค."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from collections import defaultdict
|
| 6 |
+
from collections.abc import Iterable, Sequence
|
| 7 |
+
from typing import Any
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
REQUIRED_SPLITS_06 = frozenset({"training", "validation", "test"})
|
| 11 |
+
REQUIRED_RECORD_FIELDS_06 = (
|
| 12 |
+
"formula_id", "origin_id", "writer_id", "device_id", "source_id", "split",
|
| 13 |
+
"canvas_width", "canvas_height", "symbols", "rights_track",
|
| 14 |
+
"commercial_training_allowed",
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def _identity_overlap06(records: Sequence[dict[str, Any]], field: str) -> dict[str, list[str]]:
|
| 19 |
+
"""ํ์ ๋ณ์: formula recordยทidentity field. ์๋ ์๋ฆฌ: ํ๋์ identity๊ฐ ๋ ์ด์์ split์ ๋ํ๋ ๊ฒฝ์ฐ๋ง ๋ฐํํ๋ค."""
|
| 20 |
+
|
| 21 |
+
split_by_identity: dict[str, set[str]] = defaultdict(set)
|
| 22 |
+
for record in records:
|
| 23 |
+
value = str(record.get(field) or "").strip()
|
| 24 |
+
if value:
|
| 25 |
+
split_by_identity[value].add(str(record.get("split") or ""))
|
| 26 |
+
return {
|
| 27 |
+
identity: sorted(splits)
|
| 28 |
+
for identity, splits in split_by_identity.items()
|
| 29 |
+
if len(splits) > 1
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def _valid_strokes06(strokes: Any) -> bool:
|
| 34 |
+
"""ํ์ ๋ณ์: symbol stroke payload. ์๋ ์๋ฆฌ: ๋น์ด ์์ง ์์ ํ๊ณผ ์ ํ ์ขํ ํ๋๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ๊ฒ์ฌํ๋ค."""
|
| 35 |
+
|
| 36 |
+
if not isinstance(strokes, list) or not strokes:
|
| 37 |
+
return False
|
| 38 |
+
for stroke in strokes:
|
| 39 |
+
if not isinstance(stroke, list) or not stroke:
|
| 40 |
+
return False
|
| 41 |
+
for point in stroke:
|
| 42 |
+
if not isinstance(point, dict) or "x" not in point or "y" not in point:
|
| 43 |
+
return False
|
| 44 |
+
try:
|
| 45 |
+
x, y = float(point["x"]), float(point["y"])
|
| 46 |
+
except (TypeError, ValueError):
|
| 47 |
+
return False
|
| 48 |
+
if not (-1e9 < x < 1e9 and -1e9 < y < 1e9):
|
| 49 |
+
return False
|
| 50 |
+
return True
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def audit_p_formula_records06(
|
| 54 |
+
records: Sequence[dict[str, Any]], *, minimum_independent_sources: int = 2,
|
| 55 |
+
) -> dict[str, Any]:
|
| 56 |
+
"""ํ์ ๋ณ์: ์ค์ ์ฐ์์ record. ์๋ ์๋ฆฌ: P ๊ถ๋ฆฌยทํ์ metadataยทidentity ๋์ยทgroup ์ ๋ต์ ํ ๋ฒ์ ๊ฐ์ฌํ๋ค."""
|
| 57 |
+
|
| 58 |
+
issues: list[dict[str, Any]] = []
|
| 59 |
+
formula_ids: set[str] = set()
|
| 60 |
+
origin_splits: dict[str, set[str]] = defaultdict(set)
|
| 61 |
+
split_counts: dict[str, int] = defaultdict(int)
|
| 62 |
+
symbol_counts: dict[str, int] = defaultdict(int)
|
| 63 |
+
missing_timestamp_symbols = missing_pressure_symbols = total_symbols = 0
|
| 64 |
+
|
| 65 |
+
for index, record in enumerate(records):
|
| 66 |
+
missing = [
|
| 67 |
+
field for field in REQUIRED_RECORD_FIELDS_06
|
| 68 |
+
if field not in record or record[field] is None or record[field] == ""
|
| 69 |
+
]
|
| 70 |
+
if missing:
|
| 71 |
+
issues.append({"type": "missing_fields", "record_index": index, "fields": missing})
|
| 72 |
+
continue
|
| 73 |
+
formula_id = str(record["formula_id"])
|
| 74 |
+
if formula_id in formula_ids:
|
| 75 |
+
issues.append({"type": "duplicate_formula_id", "formula_id": formula_id})
|
| 76 |
+
formula_ids.add(formula_id)
|
| 77 |
+
split = str(record["split"])
|
| 78 |
+
split_counts[split] += 1
|
| 79 |
+
if split not in REQUIRED_SPLITS_06:
|
| 80 |
+
issues.append({"type": "invalid_split", "formula_id": formula_id, "split": split})
|
| 81 |
+
origin_splits[str(record["origin_id"])].add(split)
|
| 82 |
+
if str(record["rights_track"]) != "P" or record["commercial_training_allowed"] is not True:
|
| 83 |
+
issues.append({"type": "rights_not_product_approved", "formula_id": formula_id})
|
| 84 |
+
try:
|
| 85 |
+
if float(record["canvas_width"]) <= 0 or float(record["canvas_height"]) <= 0:
|
| 86 |
+
raise ValueError
|
| 87 |
+
except (TypeError, ValueError):
|
| 88 |
+
issues.append({"type": "invalid_canvas", "formula_id": formula_id})
|
| 89 |
+
|
| 90 |
+
symbols = record["symbols"]
|
| 91 |
+
if not isinstance(symbols, list) or not symbols:
|
| 92 |
+
issues.append({"type": "empty_symbol_groups", "formula_id": formula_id})
|
| 93 |
+
continue
|
| 94 |
+
for symbol_index, symbol in enumerate(symbols):
|
| 95 |
+
total_symbols += 1
|
| 96 |
+
token = str(symbol.get("token") or "").strip() if isinstance(symbol, dict) else ""
|
| 97 |
+
if not token or not isinstance(symbol, dict) or not _valid_strokes06(symbol.get("strokes")):
|
| 98 |
+
issues.append({
|
| 99 |
+
"type": "invalid_symbol_group", "formula_id": formula_id,
|
| 100 |
+
"symbol_index": symbol_index,
|
| 101 |
+
})
|
| 102 |
+
continue
|
| 103 |
+
symbol_counts[token] += 1
|
| 104 |
+
points = [point for stroke in symbol["strokes"] for point in stroke]
|
| 105 |
+
if not all(point.get("t") is not None for point in points):
|
| 106 |
+
missing_timestamp_symbols += 1
|
| 107 |
+
if not all(point.get("pressure") is not None for point in points):
|
| 108 |
+
missing_pressure_symbols += 1
|
| 109 |
+
|
| 110 |
+
for origin, splits in origin_splits.items():
|
| 111 |
+
if len(splits) > 1:
|
| 112 |
+
issues.append({"type": "origin_split_leakage", "origin_id": origin, "splits": sorted(splits)})
|
| 113 |
+
identity_overlap = {
|
| 114 |
+
field: _identity_overlap06(records, field)
|
| 115 |
+
for field in ("writer_id", "device_id", "source_id")
|
| 116 |
+
}
|
| 117 |
+
for field, overlaps in identity_overlap.items():
|
| 118 |
+
if overlaps:
|
| 119 |
+
issues.append({
|
| 120 |
+
"type": f"{field}_split_leakage",
|
| 121 |
+
"count": len(overlaps),
|
| 122 |
+
"examples": dict(list(overlaps.items())[:10]),
|
| 123 |
+
})
|
| 124 |
+
missing_splits = sorted(REQUIRED_SPLITS_06 - set(split_counts))
|
| 125 |
+
if missing_splits:
|
| 126 |
+
issues.append({"type": "missing_required_splits", "splits": missing_splits})
|
| 127 |
+
independent_sources = len({str(record.get("source_id") or "") for record in records if record.get("source_id")})
|
| 128 |
+
if independent_sources < minimum_independent_sources:
|
| 129 |
+
issues.append({
|
| 130 |
+
"type": "insufficient_independent_sources",
|
| 131 |
+
"observed": independent_sources, "required": minimum_independent_sources,
|
| 132 |
+
})
|
| 133 |
+
|
| 134 |
+
return {
|
| 135 |
+
"schema": "aiflow-p-formula-preflight-v1",
|
| 136 |
+
"records": len(records),
|
| 137 |
+
"symbols": total_symbols,
|
| 138 |
+
"split_counts": dict(sorted(split_counts.items())),
|
| 139 |
+
"label_count": len(symbol_counts),
|
| 140 |
+
"independent_sources": independent_sources,
|
| 141 |
+
"identity_overlap_counts": {
|
| 142 |
+
field: len(overlaps) for field, overlaps in identity_overlap.items()
|
| 143 |
+
},
|
| 144 |
+
"missing_metadata_slices": {
|
| 145 |
+
"timestamp_symbols": missing_timestamp_symbols,
|
| 146 |
+
"pressure_symbols": missing_pressure_symbols,
|
| 147 |
+
},
|
| 148 |
+
"issues": issues,
|
| 149 |
+
"eligible_for_product_evaluation": not issues,
|
| 150 |
+
"product_validation": False,
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def formula_boundary_candidates06(record: dict[str, Any]) -> list[dict[str, Any]]:
|
| 155 |
+
"""ํ์ ๋ณ์: ๊ฒ์ฆ๋ formula record. ์๋ ์๋ฆฌ: ์ค์ ๋จ์ผ group๊ณผ ์ธ์ ๋ group ๊ฒฐํฉ์ boundary ์ ๋ต ํ๋ณด๋ก ๋ง๋ ๋ค."""
|
| 156 |
+
|
| 157 |
+
symbols = record["symbols"]
|
| 158 |
+
candidates = [
|
| 159 |
+
{
|
| 160 |
+
"formula_id": str(record["formula_id"]),
|
| 161 |
+
"symbol_indices": [index],
|
| 162 |
+
"strokes": symbol["strokes"],
|
| 163 |
+
"boundary_target": 0,
|
| 164 |
+
}
|
| 165 |
+
for index, symbol in enumerate(symbols)
|
| 166 |
+
]
|
| 167 |
+
for index in range(len(symbols) - 1):
|
| 168 |
+
candidates.append({
|
| 169 |
+
"formula_id": str(record["formula_id"]),
|
| 170 |
+
"symbol_indices": [index, index + 1],
|
| 171 |
+
"strokes": [*symbols[index]["strokes"], *symbols[index + 1]["strokes"]],
|
| 172 |
+
"boundary_target": 1,
|
| 173 |
+
})
|
| 174 |
+
return candidates
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def collect_formula_boundary_candidates06(
|
| 178 |
+
records: Iterable[dict[str, Any]],
|
| 179 |
+
) -> list[dict[str, Any]]:
|
| 180 |
+
"""ํ์ ๋ณ์: ๊ฒ์ฆ๋ formula iterable. ์๋ ์๋ฆฌ: formula๋ณ ์ค์ group ํ๋ณด๋ฅผ ํ๊ฐ์ฉ ํํ ๋ชฉ๋ก์ผ๋ก ๋ง๋ ๋ค."""
|
| 181 |
+
|
| 182 |
+
return [
|
| 183 |
+
candidate
|
| 184 |
+
for record in records
|
| 185 |
+
for candidate in formula_boundary_candidates06(record)
|
| 186 |
+
]
|