calibrate-pro 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. calibrate_pro-1.1.0/.github/FUNDING.yml +2 -0
  2. calibrate_pro-1.1.0/.github/workflows/ci.yml +56 -0
  3. calibrate_pro-1.1.0/.github/workflows/release.yml +203 -0
  4. calibrate_pro-1.1.0/ARCHITECTURE.md +111 -0
  5. calibrate_pro-1.1.0/AUTHORS.md +12 -0
  6. calibrate_pro-1.1.0/CHANGELOG.md +50 -0
  7. calibrate_pro-1.1.0/CONTRIBUTING.md +10 -0
  8. calibrate_pro-1.1.0/LICENSE +110 -0
  9. calibrate_pro-1.1.0/MANIFEST.in +31 -0
  10. calibrate_pro-1.1.0/PKG-INFO +245 -0
  11. calibrate_pro-1.1.0/README.md +193 -0
  12. calibrate_pro-1.1.0/RELEASE_NOTES.md +42 -0
  13. calibrate_pro-1.1.0/SECURITY.md +140 -0
  14. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Build-Color-1.0.2.txt +110 -0
  15. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Build-UI-2.0.0.txt +110 -0
  16. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/CPython-3.12.10-Windows-Externals-NOTICE.txt +732 -0
  17. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/LGPL-3.0-only.txt +165 -0
  18. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/LGPL_RELINKING.md +11 -0
  19. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Microsoft-Visual-Cpp-Runtime-NOTICE.txt +65 -0
  20. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/NumPy-2.5.1.txt +914 -0
  21. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/OpenBLAS.txt +29 -0
  22. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Packaging-26.2.txt +216 -0
  23. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/PyInstaller-6.21.0.txt +636 -0
  24. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Python-3.12.10.txt +279 -0
  25. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/QT_SOURCE_OFFER.txt +125 -0
  26. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Qt-6.11.1-THIRD-PARTY-NOTICES.txt +881 -0
  27. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/Qt-for-Python-NOTICE.txt +21 -0
  28. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/QtPy-2.4.3.txt +21 -0
  29. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/README.md +32 -0
  30. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/SciPy-1.18.0.txt +915 -0
  31. calibrate_pro-1.1.0/THIRD_PARTY_LICENSES/hidapi-0.15.0.txt +728 -0
  32. calibrate_pro-1.1.0/USAGE.md +169 -0
  33. calibrate_pro-1.1.0/calibrate-pro.spec +268 -0
  34. calibrate_pro-1.1.0/calibrate_pro/__init__.py +59 -0
  35. calibrate_pro-1.1.0/calibrate_pro/__main__.py +5 -0
  36. calibrate_pro-1.1.0/calibrate_pro/actuation.py +212 -0
  37. calibrate_pro-1.1.0/calibrate_pro/adapters/__init__.py +21 -0
  38. calibrate_pro-1.1.0/calibrate_pro/adapters/windows_display_state.py +4826 -0
  39. calibrate_pro-1.1.0/calibrate_pro/advanced/__init__.py +272 -0
  40. calibrate_pro-1.1.0/calibrate_pro/advanced/ambient_light.py +913 -0
  41. calibrate_pro-1.1.0/calibrate_pro/advanced/automation.py +1057 -0
  42. calibrate_pro-1.1.0/calibrate_pro/advanced/demo.py +359 -0
  43. calibrate_pro-1.1.0/calibrate_pro/advanced/lut_optimization.py +839 -0
  44. calibrate_pro-1.1.0/calibrate_pro/advanced/network_calibration.py +939 -0
  45. calibrate_pro-1.1.0/calibrate_pro/advanced/uniformity.py +817 -0
  46. calibrate_pro-1.1.0/calibrate_pro/app.py +25 -0
  47. calibrate_pro-1.1.0/calibrate_pro/calibration/__init__.py +14 -0
  48. calibrate_pro-1.1.0/calibrate_pro/calibration/ccss_import.py +361 -0
  49. calibrate_pro-1.1.0/calibrate_pro/calibration/hardware_first.py +367 -0
  50. calibrate_pro-1.1.0/calibrate_pro/calibration/hybrid.py +390 -0
  51. calibrate_pro-1.1.0/calibrate_pro/calibration/multi_display.py +189 -0
  52. calibrate_pro-1.1.0/calibrate_pro/calibration/native_loop.py +413 -0
  53. calibrate_pro-1.1.0/calibrate_pro/calibration/targets.py +409 -0
  54. calibrate_pro-1.1.0/calibrate_pro/commands/__init__.py +1 -0
  55. calibrate_pro-1.1.0/calibrate_pro/commands/doctor.py +14 -0
  56. calibrate_pro-1.1.0/calibrate_pro/commands/gui.py +26 -0
  57. calibrate_pro-1.1.0/calibrate_pro/commands/hdr.py +26 -0
  58. calibrate_pro-1.1.0/calibrate_pro/community/__init__.py +6 -0
  59. calibrate_pro-1.1.0/calibrate_pro/community/database.py +377 -0
  60. calibrate_pro-1.1.0/calibrate_pro/core/__init__.py +199 -0
  61. calibrate_pro-1.1.0/calibrate_pro/core/aces.py +876 -0
  62. calibrate_pro-1.1.0/calibrate_pro/core/calibration_engine.py +915 -0
  63. calibrate_pro-1.1.0/calibrate_pro/core/color_math.py +1709 -0
  64. calibrate_pro-1.1.0/calibrate_pro/core/color_models.py +925 -0
  65. calibrate_pro-1.1.0/calibrate_pro/core/icc_profile.py +592 -0
  66. calibrate_pro-1.1.0/calibrate_pro/core/lut_engine.py +1468 -0
  67. calibrate_pro-1.1.0/calibrate_pro/core/lut_engine_advanced.py +850 -0
  68. calibrate_pro-1.1.0/calibrate_pro/core/pq.py +43 -0
  69. calibrate_pro-1.1.0/calibrate_pro/core/vcgt.py +593 -0
  70. calibrate_pro-1.1.0/calibrate_pro/diagnostics.py +259 -0
  71. calibrate_pro-1.1.0/calibrate_pro/display/__init__.py +20 -0
  72. calibrate_pro-1.1.0/calibrate_pro/display/color_volume.py +231 -0
  73. calibrate_pro-1.1.0/calibrate_pro/display/hdr_content.py +342 -0
  74. calibrate_pro-1.1.0/calibrate_pro/display/hdr_detect.py +246 -0
  75. calibrate_pro-1.1.0/calibrate_pro/display/oled.py +303 -0
  76. calibrate_pro-1.1.0/calibrate_pro/display/scrgb_pipeline.py +418 -0
  77. calibrate_pro-1.1.0/calibrate_pro/display/uniformity.py +429 -0
  78. calibrate_pro-1.1.0/calibrate_pro/frozen_main.py +89 -0
  79. calibrate_pro-1.1.0/calibrate_pro/gui/__init__.py +140 -0
  80. calibrate_pro-1.1.0/calibrate_pro/gui/app.py +2110 -0
  81. calibrate_pro-1.1.0/calibrate_pro/gui/calibration_details.py +415 -0
  82. calibrate_pro-1.1.0/calibrate_pro/gui/calibration_test.py +914 -0
  83. calibrate_pro-1.1.0/calibrate_pro/gui/calibration_wizard.py +1285 -0
  84. calibrate_pro-1.1.0/calibrate_pro/gui/dialogs.py +522 -0
  85. calibrate_pro-1.1.0/calibrate_pro/gui/display_selector.py +659 -0
  86. calibrate_pro-1.1.0/calibrate_pro/gui/hdr_calibration.py +528 -0
  87. calibrate_pro-1.1.0/calibrate_pro/gui/icons.py +226 -0
  88. calibrate_pro-1.1.0/calibrate_pro/gui/lut_preview.py +783 -0
  89. calibrate_pro-1.1.0/calibrate_pro/gui/main_window.py +481 -0
  90. calibrate_pro-1.1.0/calibrate_pro/gui/measurement_view.py +572 -0
  91. calibrate_pro-1.1.0/calibrate_pro/gui/pages/__init__.py +0 -0
  92. calibrate_pro-1.1.0/calibrate_pro/gui/pages/calibrate.py +1043 -0
  93. calibrate_pro-1.1.0/calibrate_pro/gui/pages/calibration_page.py +568 -0
  94. calibrate_pro-1.1.0/calibrate_pro/gui/pages/color_control_page.py +504 -0
  95. calibrate_pro-1.1.0/calibrate_pro/gui/pages/dashboard_page.py +554 -0
  96. calibrate_pro-1.1.0/calibrate_pro/gui/pages/ddc_control.py +593 -0
  97. calibrate_pro-1.1.0/calibrate_pro/gui/pages/ddc_control_page.py +1115 -0
  98. calibrate_pro-1.1.0/calibrate_pro/gui/pages/profiles.py +582 -0
  99. calibrate_pro-1.1.0/calibrate_pro/gui/pages/profiles_page.py +734 -0
  100. calibrate_pro-1.1.0/calibrate_pro/gui/pages/settings.py +568 -0
  101. calibrate_pro-1.1.0/calibrate_pro/gui/pages/settings_page.py +229 -0
  102. calibrate_pro-1.1.0/calibrate_pro/gui/pages/vcgt_tools_page.py +274 -0
  103. calibrate_pro-1.1.0/calibrate_pro/gui/pages/verification_page.py +335 -0
  104. calibrate_pro-1.1.0/calibrate_pro/gui/pages/verify.py +1273 -0
  105. calibrate_pro-1.1.0/calibrate_pro/gui/pattern_window.py +763 -0
  106. calibrate_pro-1.1.0/calibrate_pro/gui/professional_calibration.py +1079 -0
  107. calibrate_pro-1.1.0/calibrate_pro/gui/profile_manager.py +367 -0
  108. calibrate_pro-1.1.0/calibrate_pro/gui/report_viewer.py +591 -0
  109. calibrate_pro-1.1.0/calibrate_pro/gui/theme.py +92 -0
  110. calibrate_pro-1.1.0/calibrate_pro/gui/widgets/__init__.py +99 -0
  111. calibrate_pro-1.1.0/calibrate_pro/gui/widgets/cie_diagram.py +826 -0
  112. calibrate_pro-1.1.0/calibrate_pro/gui/widgets/color_swatch.py +449 -0
  113. calibrate_pro-1.1.0/calibrate_pro/gui/widgets/delta_e_chart.py +462 -0
  114. calibrate_pro-1.1.0/calibrate_pro/gui/widgets/gamma_curve.py +482 -0
  115. calibrate_pro-1.1.0/calibrate_pro/gui/workers.py +103 -0
  116. calibrate_pro-1.1.0/calibrate_pro/hardware/__init__.py +443 -0
  117. calibrate_pro-1.1.0/calibrate_pro/hardware/argyll_backend.py +699 -0
  118. calibrate_pro-1.1.0/calibrate_pro/hardware/colorimeter_base.py +503 -0
  119. calibrate_pro-1.1.0/calibrate_pro/hardware/ddc_ci.py +1632 -0
  120. calibrate_pro-1.1.0/calibrate_pro/hardware/drift_compensation.py +174 -0
  121. calibrate_pro-1.1.0/calibrate_pro/hardware/hardware_calibration.py +869 -0
  122. calibrate_pro-1.1.0/calibrate_pro/hardware/i1d3_native.py +565 -0
  123. calibrate_pro-1.1.0/calibrate_pro/hardware/i1display.py +351 -0
  124. calibrate_pro-1.1.0/calibrate_pro/hardware/i1display_native.py +485 -0
  125. calibrate_pro-1.1.0/calibrate_pro/hardware/measurement.py +262 -0
  126. calibrate_pro-1.1.0/calibrate_pro/hardware/native_backend.py +268 -0
  127. calibrate_pro-1.1.0/calibrate_pro/hardware/sensorless_calibration.py +1928 -0
  128. calibrate_pro-1.1.0/calibrate_pro/hardware/spectro.py +394 -0
  129. calibrate_pro-1.1.0/calibrate_pro/hardware/spyder.py +392 -0
  130. calibrate_pro-1.1.0/calibrate_pro/hardware/spyder_native.py +490 -0
  131. calibrate_pro-1.1.0/calibrate_pro/hardware/usb_device.py +379 -0
  132. calibrate_pro-1.1.0/calibrate_pro/hardware/warmup_monitor.py +192 -0
  133. calibrate_pro-1.1.0/calibrate_pro/hdr/__init__.py +446 -0
  134. calibrate_pro-1.1.0/calibrate_pro/hdr/dolby_vision.py +622 -0
  135. calibrate_pro-1.1.0/calibrate_pro/hdr/eotf_calibration.py +654 -0
  136. calibrate_pro-1.1.0/calibrate_pro/hdr/hdr10plus.py +613 -0
  137. calibrate_pro-1.1.0/calibrate_pro/hdr/hdr_calibration.py +631 -0
  138. calibrate_pro-1.1.0/calibrate_pro/hdr/hlg.py +339 -0
  139. calibrate_pro-1.1.0/calibrate_pro/hdr/mastering_standards.py +511 -0
  140. calibrate_pro-1.1.0/calibrate_pro/hdr/pq_st2084.py +349 -0
  141. calibrate_pro-1.1.0/calibrate_pro/hdr/tone_mapping.py +541 -0
  142. calibrate_pro-1.1.0/calibrate_pro/hdr/workflow.py +400 -0
  143. calibrate_pro-1.1.0/calibrate_pro/integrations/__init__.py +1 -0
  144. calibrate_pro-1.1.0/calibrate_pro/integrations/resolve.py +133 -0
  145. calibrate_pro-1.1.0/calibrate_pro/lut_system/__init__.py +589 -0
  146. calibrate_pro-1.1.0/calibrate_pro/lut_system/amd_api.py +1374 -0
  147. calibrate_pro-1.1.0/calibrate_pro/lut_system/color_loader.py +726 -0
  148. calibrate_pro-1.1.0/calibrate_pro/lut_system/dwm_lut.py +1186 -0
  149. calibrate_pro-1.1.0/calibrate_pro/lut_system/intel_api.py +350 -0
  150. calibrate_pro-1.1.0/calibrate_pro/lut_system/lut_formats.py +890 -0
  151. calibrate_pro-1.1.0/calibrate_pro/lut_system/nvidia_api.py +1138 -0
  152. calibrate_pro-1.1.0/calibrate_pro/lut_system/per_display_calibration.py +556 -0
  153. calibrate_pro-1.1.0/calibrate_pro/lut_system/vcgt_calibration.py +459 -0
  154. calibrate_pro-1.1.0/calibrate_pro/main.py +305 -0
  155. calibrate_pro-1.1.0/calibrate_pro/panels/__init__.py +1 -0
  156. calibrate_pro-1.1.0/calibrate_pro/panels/builtin_panels.py +2735 -0
  157. calibrate_pro-1.1.0/calibrate_pro/panels/database.py +247 -0
  158. calibrate_pro-1.1.0/calibrate_pro/panels/detection.py +2288 -0
  159. calibrate_pro-1.1.0/calibrate_pro/panels/panel_types.py +167 -0
  160. calibrate_pro-1.1.0/calibrate_pro/patterns/__init__.py +10 -0
  161. calibrate_pro-1.1.0/calibrate_pro/patterns/display.py +369 -0
  162. calibrate_pro-1.1.0/calibrate_pro/platform/__init__.py +60 -0
  163. calibrate_pro-1.1.0/calibrate_pro/platform/base.py +145 -0
  164. calibrate_pro-1.1.0/calibrate_pro/platform/linux.py +751 -0
  165. calibrate_pro-1.1.0/calibrate_pro/platform/macos.py +415 -0
  166. calibrate_pro-1.1.0/calibrate_pro/platform/windows.py +174 -0
  167. calibrate_pro-1.1.0/calibrate_pro/plugins/__init__.py +18 -0
  168. calibrate_pro-1.1.0/calibrate_pro/plugins/manager.py +380 -0
  169. calibrate_pro-1.1.0/calibrate_pro/profiles/__init__.py +242 -0
  170. calibrate_pro-1.1.0/calibrate_pro/profiles/icc_v4.py +870 -0
  171. calibrate_pro-1.1.0/calibrate_pro/profiles/mhc2.py +1110 -0
  172. calibrate_pro-1.1.0/calibrate_pro/profiles/profile_installer.py +2825 -0
  173. calibrate_pro-1.1.0/calibrate_pro/profiles/vcgt.py +762 -0
  174. calibrate_pro-1.1.0/calibrate_pro/qt_runtime.py +22 -0
  175. calibrate_pro-1.1.0/calibrate_pro/recovery.py +394 -0
  176. calibrate_pro-1.1.0/calibrate_pro/resources/calibrate_pro.ico +0 -0
  177. calibrate_pro-1.1.0/calibrate_pro/resources/calibrate_pro.png +0 -0
  178. calibrate_pro-1.1.0/calibrate_pro/runtime.py +18 -0
  179. calibrate_pro-1.1.0/calibrate_pro/sensorless/__init__.py +117 -0
  180. calibrate_pro-1.1.0/calibrate_pro/sensorless/auto_calibration.py +1863 -0
  181. calibrate_pro-1.1.0/calibrate_pro/sensorless/camera_calibration.py +682 -0
  182. calibrate_pro-1.1.0/calibrate_pro/sensorless/neuralux.py +965 -0
  183. calibrate_pro-1.1.0/calibrate_pro/sensorless/pattern_generator.py +356 -0
  184. calibrate_pro-1.1.0/calibrate_pro/sensorless/visual_matcher.py +427 -0
  185. calibrate_pro-1.1.0/calibrate_pro/services/__init__.py +18 -0
  186. calibrate_pro-1.1.0/calibrate_pro/services/ambient_light.py +417 -0
  187. calibrate_pro-1.1.0/calibrate_pro/services/app_switcher.py +425 -0
  188. calibrate_pro-1.1.0/calibrate_pro/services/calibration_guard.py +244 -0
  189. calibrate_pro-1.1.0/calibrate_pro/services/drift_monitor.py +183 -0
  190. calibrate_pro-1.1.0/calibrate_pro/services/gamut_clamp.py +117 -0
  191. calibrate_pro-1.1.0/calibrate_pro/startup/__init__.py +27 -0
  192. calibrate_pro-1.1.0/calibrate_pro/startup/calibration_loader.py +161 -0
  193. calibrate_pro-1.1.0/calibrate_pro/startup/lut_autoload.py +99 -0
  194. calibrate_pro-1.1.0/calibrate_pro/targets/__init__.py +359 -0
  195. calibrate_pro-1.1.0/calibrate_pro/targets/gamma.py +632 -0
  196. calibrate_pro-1.1.0/calibrate_pro/targets/gamut.py +613 -0
  197. calibrate_pro-1.1.0/calibrate_pro/targets/luminance.py +618 -0
  198. calibrate_pro-1.1.0/calibrate_pro/targets/whitepoint.py +475 -0
  199. calibrate_pro-1.1.0/calibrate_pro/tray/__init__.py +10 -0
  200. calibrate_pro-1.1.0/calibrate_pro/tray/tray_app.py +281 -0
  201. calibrate_pro-1.1.0/calibrate_pro/utils/__init__.py +1 -0
  202. calibrate_pro-1.1.0/calibrate_pro/utils/auto_calibration.py +530 -0
  203. calibrate_pro-1.1.0/calibrate_pro/utils/startup_manager.py +257 -0
  204. calibrate_pro-1.1.0/calibrate_pro/verification/__init__.py +318 -0
  205. calibrate_pro-1.1.0/calibrate_pro/verification/colorchecker.py +716 -0
  206. calibrate_pro-1.1.0/calibrate_pro/verification/gamut_volume.py +958 -0
  207. calibrate_pro-1.1.0/calibrate_pro/verification/grayscale.py +887 -0
  208. calibrate_pro-1.1.0/calibrate_pro/verification/measured_verify.py +640 -0
  209. calibrate_pro-1.1.0/calibrate_pro/verification/patch_sets.py +707 -0
  210. calibrate_pro-1.1.0/calibrate_pro/verification/pdf_export.py +110 -0
  211. calibrate_pro-1.1.0/calibrate_pro/verification/provenance.py +49 -0
  212. calibrate_pro-1.1.0/calibrate_pro/verification/report_generator.py +1436 -0
  213. calibrate_pro-1.1.0/calibrate_pro/verification/reports.py +1228 -0
  214. calibrate_pro-1.1.0/calibrate_pro/workflow.py +250 -0
  215. calibrate_pro-1.1.0/calibrate_pro.egg-info/PKG-INFO +245 -0
  216. calibrate_pro-1.1.0/calibrate_pro.egg-info/SOURCES.txt +311 -0
  217. calibrate_pro-1.1.0/calibrate_pro.egg-info/dependency_links.txt +1 -0
  218. calibrate_pro-1.1.0/calibrate_pro.egg-info/entry_points.txt +2 -0
  219. calibrate_pro-1.1.0/calibrate_pro.egg-info/requires.txt +42 -0
  220. calibrate_pro-1.1.0/calibrate_pro.egg-info/top_level.txt +1 -0
  221. calibrate_pro-1.1.0/docs/ENTERPRISE-READINESS.md +84 -0
  222. calibrate_pro-1.1.0/docs/INDUSTRY_FEATURES.md +98 -0
  223. calibrate_pro-1.1.0/docs/TECHNICAL.md +147 -0
  224. calibrate_pro-1.1.0/docs/UI_ROADMAP.md +240 -0
  225. calibrate_pro-1.1.0/docs/brand/README.md +15 -0
  226. calibrate_pro-1.1.0/docs/brand/calibrate-pro-hero.png +0 -0
  227. calibrate_pro-1.1.0/docs/brand/calibrate-pro-hero.svg +18 -0
  228. calibrate_pro-1.1.0/docs/brand/calibrate-pro-mark.svg +8 -0
  229. calibrate_pro-1.1.0/docs/index.html +179 -0
  230. calibrate_pro-1.1.0/docs/superpowers/plans/2026-07-10-calibrate-pro-1.1-pyside-packaging.md +2495 -0
  231. calibrate_pro-1.1.0/docs/superpowers/specs/2026-07-09-calibrate-pro-packaging-polish-design.md +531 -0
  232. calibrate_pro-1.1.0/docs/superpowers/specs/2026-07-10-cp-hdr-1-measured-display-characterization-design.md +452 -0
  233. calibrate_pro-1.1.0/dwm_lut/DwmLutGUI.exe +0 -0
  234. calibrate_pro-1.1.0/dwm_lut/LICENSE +674 -0
  235. calibrate_pro-1.1.0/dwm_lut/LICENSE-THIRD-PARTY +493 -0
  236. calibrate_pro-1.1.0/dwm_lut/WindowsDisplayAPI.dll +0 -0
  237. calibrate_pro-1.1.0/dwm_lut/dwm_lut.dll +0 -0
  238. calibrate_pro-1.1.0/examples/inspect_panels.py +59 -0
  239. calibrate_pro-1.1.0/installer/CalibratePro.iss +43 -0
  240. calibrate_pro-1.1.0/packaging/binary-provenance.lock.json +142 -0
  241. calibrate_pro-1.1.0/packaging/components-win64.json +1030 -0
  242. calibrate_pro-1.1.0/packaging/frozen-features.json +34 -0
  243. calibrate_pro-1.1.0/packaging/frozen-modules.json +135 -0
  244. calibrate_pro-1.1.0/packaging/pyi_rth_qt_api.py +6 -0
  245. calibrate_pro-1.1.0/packaging/qt-components.json +70 -0
  246. calibrate_pro-1.1.0/packaging/requirements-win64-py312.lock +480 -0
  247. calibrate_pro-1.1.0/packaging/requirements-win64.in +13 -0
  248. calibrate_pro-1.1.0/packaging/source-provenance.lock.json +222 -0
  249. calibrate_pro-1.1.0/packaging/toolchain-win64.json +15 -0
  250. calibrate_pro-1.1.0/pyproject.toml +122 -0
  251. calibrate_pro-1.1.0/scripts/build_windows.ps1 +325 -0
  252. calibrate_pro-1.1.0/scripts/ccmx_calibration_loop.py +441 -0
  253. calibrate_pro-1.1.0/scripts/ccmx_chroma_adaptive.py +374 -0
  254. calibrate_pro-1.1.0/scripts/ccmx_verification.py +313 -0
  255. calibrate_pro-1.1.0/scripts/hybrid_measure.py +282 -0
  256. calibrate_pro-1.1.0/scripts/native_calibration_loop.py +629 -0
  257. calibrate_pro-1.1.0/scripts/native_calibration_loop_v2.py +641 -0
  258. calibrate_pro-1.1.0/scripts/native_colorchecker.py +243 -0
  259. calibrate_pro-1.1.0/scripts/native_iterative_refine.py +385 -0
  260. calibrate_pro-1.1.0/scripts/normalize_sdist.py +117 -0
  261. calibrate_pro-1.1.0/scripts/release_artifacts.py +891 -0
  262. calibrate_pro-1.1.0/scripts/smoke_frozen.ps1 +51 -0
  263. calibrate_pro-1.1.0/scripts/unlock_measure.py +136 -0
  264. calibrate_pro-1.1.0/scripts/vcgt_measure.py +221 -0
  265. calibrate_pro-1.1.0/scripts/verify_binary_provenance.py +173 -0
  266. calibrate_pro-1.1.0/scripts/verify_pe_manifest.py +90 -0
  267. calibrate_pro-1.1.0/scripts/verify_release_asset_set.py +97 -0
  268. calibrate_pro-1.1.0/scripts/verify_reproducibility.ps1 +70 -0
  269. calibrate_pro-1.1.0/scripts/verify_source_provenance.py +211 -0
  270. calibrate_pro-1.1.0/setup.cfg +4 -0
  271. calibrate_pro-1.1.0/tests/__init__.py +0 -0
  272. calibrate_pro-1.1.0/tests/conftest.py +70 -0
  273. calibrate_pro-1.1.0/tests/data/gui-public-api-1.0.json +19 -0
  274. calibrate_pro-1.1.0/tests/data/st2084-gold-vectors.json +15 -0
  275. calibrate_pro-1.1.0/tests/test_actuator_boundary.py +447 -0
  276. calibrate_pro-1.1.0/tests/test_auto_calibration.py +310 -0
  277. calibrate_pro-1.1.0/tests/test_binary_provenance.py +85 -0
  278. calibrate_pro-1.1.0/tests/test_color_math.py +458 -0
  279. calibrate_pro-1.1.0/tests/test_ddc_ci_safety.py +471 -0
  280. calibrate_pro-1.1.0/tests/test_diagnostics.py +316 -0
  281. calibrate_pro-1.1.0/tests/test_frozen_module_allowlist.py +169 -0
  282. calibrate_pro-1.1.0/tests/test_gui_lazy_imports.py +83 -0
  283. calibrate_pro-1.1.0/tests/test_gui_truthfulness.py +118 -0
  284. calibrate_pro-1.1.0/tests/test_hdr_provenance.py +193 -0
  285. calibrate_pro-1.1.0/tests/test_hdr_workflow.py +446 -0
  286. calibrate_pro-1.1.0/tests/test_least_privilege.py +218 -0
  287. calibrate_pro-1.1.0/tests/test_lut_engine.py +239 -0
  288. calibrate_pro-1.1.0/tests/test_native_loop.py +159 -0
  289. calibrate_pro-1.1.0/tests/test_packaging_contract.py +200 -0
  290. calibrate_pro-1.1.0/tests/test_panel_database.py +204 -0
  291. calibrate_pro-1.1.0/tests/test_pdf_export.py +94 -0
  292. calibrate_pro-1.1.0/tests/test_platform.py +711 -0
  293. calibrate_pro-1.1.0/tests/test_pq_conformance.py +217 -0
  294. calibrate_pro-1.1.0/tests/test_professional_features.py +222 -0
  295. calibrate_pro-1.1.0/tests/test_profile_installer_portability.py +32 -0
  296. calibrate_pro-1.1.0/tests/test_profile_installer_safety.py +3293 -0
  297. calibrate_pro-1.1.0/tests/test_public_release_docs.py +149 -0
  298. calibrate_pro-1.1.0/tests/test_pypi_release_workflow.py +169 -0
  299. calibrate_pro-1.1.0/tests/test_python_compatibility.py +46 -0
  300. calibrate_pro-1.1.0/tests/test_qt_binding_contract.py +139 -0
  301. calibrate_pro-1.1.0/tests/test_qt_redistribution.py +301 -0
  302. calibrate_pro-1.1.0/tests/test_release_artifacts.py +641 -0
  303. calibrate_pro-1.1.0/tests/test_release_asset_set.py +50 -0
  304. calibrate_pro-1.1.0/tests/test_release_lock.py +88 -0
  305. calibrate_pro-1.1.0/tests/test_release_metadata.py +91 -0
  306. calibrate_pro-1.1.0/tests/test_release_pipeline_contract.py +119 -0
  307. calibrate_pro-1.1.0/tests/test_report_truthfulness.py +136 -0
  308. calibrate_pro-1.1.0/tests/test_sdist_reproducibility.py +74 -0
  309. calibrate_pro-1.1.0/tests/test_truthfulness_contract.py +137 -0
  310. calibrate_pro-1.1.0/tests/test_verification.py +139 -0
  311. calibrate_pro-1.1.0/tests/test_windows_ctypes_abi.py +1343 -0
  312. calibrate_pro-1.1.0/tests/test_windows_display_state_adapter.py +9430 -0
  313. calibrate_pro-1.1.0/tests/test_workflow.py +1076 -0
@@ -0,0 +1,2 @@
1
+ github: HarperZ9
2
+ custom: ["https://harperz9.github.io", "https://harperz9.github.io/field-guide.html"]
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
14
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
15
+ with:
16
+ python-version: "3.12"
17
+ - name: Install pinned ruff + mypy
18
+ run: pip install ruff==0.15.21 mypy==2.2.0
19
+ - name: Lint
20
+ run: ruff check .
21
+ - name: Format check
22
+ run: ruff format --check .
23
+ - name: Type check (mypy)
24
+ run: mypy --platform win32
25
+
26
+ test:
27
+ runs-on: ${{ matrix.os }}
28
+ env:
29
+ QT_API: pyside6
30
+ QT_QPA_PLATFORM: offscreen
31
+ strategy:
32
+ matrix:
33
+ os: [ubuntu-latest, windows-latest]
34
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
35
+ steps:
36
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
37
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+ - name: Install Linux Qt runtime libraries
41
+ if: runner.os == 'Linux'
42
+ run: |
43
+ sudo apt-get update
44
+ sudo apt-get install -y libegl1 libxkbcommon0
45
+ - name: Install dependencies
46
+ run: |
47
+ python -m pip install --upgrade pip
48
+ python -m pip install -e ".[all,test]"
49
+ - name: Run portable tests with coverage
50
+ if: runner.os == 'Linux'
51
+ run: pytest tests/ -q -m "not windows" --cov=calibrate_pro --cov-report=term-missing --cov-fail-under=15
52
+ - name: Run complete Windows tests with coverage
53
+ if: runner.os == 'Windows'
54
+ env:
55
+ COVERAGE_CORE: ${{ matrix.python-version == '3.12' && 'sysmon' || 'ctrace' }}
56
+ run: pytest tests/ -q --cov=calibrate_pro --cov-report=term-missing --cov-fail-under=15
@@ -0,0 +1,203 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ publish:
7
+ description: Publish the already accepted release assets to PyPI
8
+ required: true
9
+ type: boolean
10
+ default: false
11
+ release_tag:
12
+ description: Existing GitHub release tag whose assets were accepted
13
+ required: true
14
+ type: string
15
+ default: v1.1.0
16
+ release:
17
+ types: [published]
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ env:
23
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
24
+
25
+ jobs:
26
+ candidate:
27
+ runs-on: ubuntu-latest
28
+ env:
29
+ QT_API: pyside6
30
+ QT_QPA_PLATFORM: offscreen
31
+ steps:
32
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
33
+ with:
34
+ ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
35
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
36
+ with:
37
+ python-version: "3.12"
38
+ - name: Install Linux Qt runtime libraries
39
+ run: |
40
+ sudo apt-get update
41
+ sudo apt-get install -y libegl1 libxkbcommon0
42
+ - name: Install candidate and verification tools
43
+ run: |
44
+ python -m pip install --upgrade build pytest pytest-cov twine
45
+ python -m pip install ".[all,test]"
46
+ - name: Verify source candidate
47
+ run: python -m pytest -q -m "not windows"
48
+ - name: Verify corresponding-source archives
49
+ run: python scripts/verify_source_provenance.py packaging/source-provenance.lock.json
50
+ - name: Build distributions
51
+ run: python -m build
52
+ - name: Check distributions
53
+ run: python -m twine check dist/*
54
+
55
+ windows-candidate:
56
+ runs-on: windows-2022
57
+ env:
58
+ QT_API: pyside6
59
+ QT_QPA_PLATFORM: offscreen
60
+ steps:
61
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
62
+ with:
63
+ ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
64
+ - name: Install the hash-locked official CPython release runtime
65
+ shell: pwsh
66
+ run: |
67
+ $binaryLock = Get-Content -Raw -LiteralPath 'packaging/binary-provenance.lock.json' | ConvertFrom-Json
68
+ $pythonEntries = @(
69
+ $binaryLock.components | Where-Object { $_.name -eq 'cpython-3.12.10-amd64-installer' }
70
+ )
71
+ if ($pythonEntries.Count -ne 1) { throw "Expected exactly one locked CPython installer; found $($pythonEntries.Count)" }
72
+ $pythonEntry = $pythonEntries[0]
73
+ if ($pythonEntry.version -ne '3.12.10' -or $pythonEntry.artifact_type -ne 'exe') {
74
+ throw 'The locked CPython release runtime does not match the approved toolchain'
75
+ }
76
+ $pythonUri = [Uri]$pythonEntry.artifact_url
77
+ if ($pythonUri.Scheme -ne 'https' -or @($pythonEntry.allowed_final_hosts) -notcontains $pythonUri.Host) {
78
+ throw "The locked CPython installer URL is not an approved HTTPS origin: $pythonUri"
79
+ }
80
+ $pythonInstaller = Join-Path $env:RUNNER_TEMP ([string]$pythonEntry.filename)
81
+ $pythonRoot = Join-Path $env:RUNNER_TEMP 'python-3.12.10-official'
82
+ Invoke-WebRequest -Uri $pythonEntry.artifact_url -MaximumRedirection 0 -OutFile $pythonInstaller
83
+ $actualHash = (Get-FileHash -LiteralPath $pythonInstaller -Algorithm SHA256).Hash.ToLowerInvariant()
84
+ if ($actualHash -ne [string]$pythonEntry.sha256) { throw "Unexpected CPython installer hash: $actualHash" }
85
+ $signature = Get-AuthenticodeSignature -LiteralPath $pythonInstaller
86
+ if ($signature.Status -ne 'Valid' -or $signature.SignerCertificate.Subject -notmatch 'Python Software Foundation') {
87
+ throw "CPython installer signature is not valid for the Python Software Foundation: $($signature.Status)"
88
+ }
89
+ $pythonInstall = Start-Process -FilePath $pythonInstaller `
90
+ -ArgumentList @(
91
+ '/quiet', 'InstallAllUsers=0', "TargetDir=$pythonRoot", 'Include_launcher=0',
92
+ 'InstallLauncherAllUsers=0', 'Include_test=0', 'Include_doc=0', 'Shortcuts=0',
93
+ 'AssociateFiles=0', 'PrependPath=0', 'AppendPath=0'
94
+ ) -Wait -PassThru -WindowStyle Hidden
95
+ if ($pythonInstall.ExitCode -ne 0) { throw "CPython installation failed: $($pythonInstall.ExitCode)" }
96
+ $python = Join-Path $pythonRoot 'python.exe'
97
+ if (-not (Test-Path -LiteralPath $python -PathType Leaf)) { throw 'The official CPython runtime was not installed' }
98
+ $actualVersion = (& $python -c 'import platform; print(platform.python_version())').Trim()
99
+ if ($actualVersion -ne [string]$pythonEntry.version) { throw "Unexpected CPython runtime version: $actualVersion" }
100
+ foreach ($runtimeName in @('libcrypto-3.dll', 'libssl-3.dll')) {
101
+ if (-not (Test-Path -LiteralPath (Join-Path $pythonRoot "DLLs\$runtimeName") -PathType Leaf)) {
102
+ throw "The official CPython runtime is missing its classified OpenSSL library: $runtimeName"
103
+ }
104
+ }
105
+ "CALIBRATE_PRO_RELEASE_PYTHON=$python" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
106
+ - name: Install the pinned host verification environment
107
+ run: |
108
+ & $env:CALIBRATE_PRO_RELEASE_PYTHON -m pip install --disable-pip-version-check --require-hashes -r packaging/requirements-win64-py312.lock
109
+ & $env:CALIBRATE_PRO_RELEASE_PYTHON -m pip install --disable-pip-version-check pytest==9.0.3
110
+ - name: Install the pinned Inno Setup compiler
111
+ shell: pwsh
112
+ run: |
113
+ $installer = Join-Path $env:RUNNER_TEMP 'innosetup-6.7.3.exe'
114
+ $innoRoot = Join-Path $env:RUNNER_TEMP 'inno-6.7.3'
115
+ Invoke-WebRequest -Uri 'https://github.com/jrsoftware/issrc/releases/download/is-6_7_3/innosetup-6.7.3.exe' -OutFile $installer
116
+ $expectedInstaller = '9c73c3bae7ed48d44112a0f48e66742c00090bdb5bef71d9d3c056c66e97b732'
117
+ $actualInstaller = (Get-FileHash -LiteralPath $installer -Algorithm SHA256).Hash.ToLowerInvariant()
118
+ if ($actualInstaller -ne $expectedInstaller) { throw "Unexpected Inno installer hash: $actualInstaller" }
119
+ $signature = Get-AuthenticodeSignature -LiteralPath $installer
120
+ if ($signature.Status -ne 'Valid') { throw "Inno installer signature is not valid: $($signature.Status)" }
121
+ $innoInstall = Start-Process -FilePath $installer `
122
+ -ArgumentList @('/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', '/CURRENTUSER', "/DIR=$innoRoot") `
123
+ -Wait -PassThru -WindowStyle Hidden
124
+ if ($innoInstall.ExitCode -ne 0) { throw "Inno installation failed: $($innoInstall.ExitCode)" }
125
+ $iscc = Join-Path $innoRoot 'ISCC.exe'
126
+ if (-not (Test-Path -LiteralPath $iscc -PathType Leaf)) { throw 'ISCC.exe was not installed' }
127
+ "CALIBRATE_PRO_ISCC=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
128
+ - name: Build and verify the complete unsigned Windows candidate
129
+ shell: pwsh
130
+ run: ./scripts/build_windows.ps1 -Unsigned -OutputRoot (Join-Path $env:RUNNER_TEMP 'calibrate-release')
131
+ - name: Verify unsigned reproducibility
132
+ shell: pwsh
133
+ run: ./scripts/verify_reproducibility.ps1
134
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
135
+ with:
136
+ name: windows-release-candidate
137
+ path: ${{ runner.temp }}\calibrate-release\release\
138
+ if-no-files-found: error
139
+
140
+ verify-publish-assets:
141
+ if: github.event_name == 'release' || inputs.publish
142
+ needs: [candidate, windows-candidate]
143
+ runs-on: ubuntu-latest
144
+ permissions:
145
+ actions: read
146
+ contents: read
147
+ steps:
148
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
149
+ with:
150
+ ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
151
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
152
+ with:
153
+ python-version: "3.12"
154
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
155
+ with:
156
+ name: windows-release-candidate
157
+ path: windows-candidate
158
+ - name: Download the exact accepted GitHub release assets
159
+ env:
160
+ GH_TOKEN: ${{ github.token }}
161
+ RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
162
+ run: gh release download "$RELEASE_TAG" --dir accepted --repo "$GITHUB_REPOSITORY"
163
+ - name: Verify the accepted release-asset hashes
164
+ working-directory: accepted
165
+ run: sha256sum --check SHA256SUMS.txt
166
+ - name: Verify the exact accepted release-asset set
167
+ run: |
168
+ python scripts/verify_release_asset_set.py accepted
169
+ python scripts/verify_release_asset_set.py windows-candidate
170
+ - name: Match accepted Python distributions to the tag-built Windows candidate
171
+ env:
172
+ RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}
173
+ run: |
174
+ test "$RELEASE_TAG" = "v1.1.0"
175
+ cmp --silent accepted/calibrate_pro-1.1.0-py3-none-any.whl windows-candidate/calibrate_pro-1.1.0-py3-none-any.whl
176
+ cmp --silent accepted/calibrate_pro-1.1.0.tar.gz windows-candidate/calibrate_pro-1.1.0.tar.gz
177
+ mkdir pypi-dist
178
+ cp accepted/calibrate_pro-1.1.0-py3-none-any.whl pypi-dist/
179
+ cp accepted/calibrate_pro-1.1.0.tar.gz pypi-dist/
180
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
181
+ with:
182
+ name: verified-pypi-distributions
183
+ path: pypi-dist/
184
+ if-no-files-found: error
185
+ retention-days: 1
186
+
187
+ publish:
188
+ if: github.event_name == 'release' || inputs.publish
189
+ needs: verify-publish-assets
190
+ runs-on: ubuntu-latest
191
+ environment: pypi
192
+ permissions:
193
+ actions: read
194
+ id-token: write
195
+ steps:
196
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
197
+ with:
198
+ name: verified-pypi-distributions
199
+ path: pypi-dist
200
+ - name: Publish verified distributions to PyPI
201
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
202
+ with:
203
+ packages-dir: pypi-dist/
@@ -0,0 +1,111 @@
1
+ # Architecture
2
+
3
+ Calibrate Pro 1.1 separates color computation, workflow policy, user confirmation, and
4
+ Windows display actuation. The central rule is simple: application-facing code can
5
+ propose a display change, but only the confirmation coordinator and canonical Windows
6
+ adapter can execute it.
7
+
8
+ ## Layers
9
+
10
+ ```text
11
+ calibrate_pro/
12
+ core/ color math, profiles, LUT generation, transforms
13
+ targets/ SDR/HDR calibration target definitions
14
+ panels/ characterized-panel data and read-only detection
15
+ calibration/ instrument measurement and calibration algorithms
16
+ sensorless/ characterization-derived estimation algorithms
17
+ verification/ evidence types, patch analysis, reports, PDF export
18
+
19
+ workflow.py pure six-stage state machine and immutable ApplyPlan
20
+ actuation.py one-use confirmation and transaction coordination
21
+ recovery.py transaction phases, compensation, and receipts
22
+ diagnostics.py deterministic, read-only installation report
23
+ runtime.py source/frozen resource resolution
24
+
25
+ adapters/
26
+ windows_display_state.py
27
+ canonical DDC/CI, ICC, VCGT, and DWM write boundary
28
+
29
+ gui/ PySide6 presentation; emits proposals, never raw writes
30
+ commands/ unelevated desktop/HDR launch and read-only doctor command
31
+ main.py read-only CLI dispatch and proposal-only legacy names
32
+ frozen_main.py two frozen executable entry points
33
+ ```
34
+
35
+ Low-level Windows modules still contain native API wrappers. Application code cannot
36
+ import or call their writer primitives directly; `DefaultWindowsDisplayAdapter` is the
37
+ sole production bridge from a confirmed transaction to those wrappers.
38
+
39
+ ## Workflow
40
+
41
+ The user-visible state machine is:
42
+
43
+ ```text
44
+ Detect -> Method -> Preview -> Apply -> Verify -> Save/Report
45
+ ```
46
+
47
+ 1. Detection gathers display identity and capability information without granting write
48
+ authority.
49
+ 2. Method selection chooses sensorless or measured evidence.
50
+ 3. Preview constructs an immutable `ApplyPlan`. External ICC, VCGT, and DWM inputs are
51
+ bounded and bound to the plan by SHA-256.
52
+ 4. Confirmation is consumed once. The coordinator revalidates capabilities and hands an
53
+ opaque authorization to the adapter while holding the apply gate.
54
+ 5. The adapter captures the requested prior state, applies the sealed plan, and reads the
55
+ result back. A failure invokes compensation and verifies that compensation before it
56
+ reports restoration.
57
+ 6. Verification and reports preserve the evidence kind and source of every performance
58
+ metric.
59
+
60
+ Rejecting, expiring, copying, substituting, or mutating a plan does not authorize a
61
+ write. Legacy mutation-capable CLI names are proposal-only and return without changing
62
+ display state.
63
+
64
+ ## Capability and recovery model
65
+
66
+ `CapabilityState` distinguishes sensor, DDC/CI, DWM write, authoritative DWM capture,
67
+ ICC association, and VCGT capabilities. A requested operation is disabled unless its
68
+ capability is positively present. In particular, DWM application requires both write
69
+ support and authoritative prior-state capture; process-local LUT memory is not accepted
70
+ as evidence of operating-system state.
71
+
72
+ Transactions use per-display process and Windows named mutexes. ICC content-addressed
73
+ cache operations also use a digest-scoped mutex and native file lease. Native resources
74
+ remain registered until cleanup is positively known, and uncertain outcomes fail closed.
75
+ Recovery is an in-process compensating transaction rather than a promise of crash-safe
76
+ rollback across power loss or operating-system termination.
77
+
78
+ ## Evidence model
79
+
80
+ Performance fields cross the report boundary as `MetricValue`, not bare numbers. Each is
81
+ labelled `measured`, `estimated`, `simulated`, `replayed`, or `not_measured`, and numeric
82
+ values retain a source receipt. Sensorless computation can inform a plan, but it does not
83
+ become an observation of the attached display.
84
+
85
+ ## Entry points
86
+
87
+ - `CalibratePro.exe` / `calibrate-pro gui`: main PySide6 workflow.
88
+ - `CalibrateProCLI.exe`: frozen `doctor`, `gui`, and `hdr` dispatcher; `hdr` opens the
89
+ HDR target/proposal workflow.
90
+ - `calibrate-pro doctor [--json]`: deterministic, read-only installation diagnostics.
91
+ - `list-targets`, `list-panels`, `info`, `hdr-status`, `patterns`, and `plugins`:
92
+ read-only or visual-inspection utilities.
93
+ - Tray and calibration guard: monitor-and-notify only in 1.1.
94
+
95
+ Both frozen executables use `asInvoker`; the installer is per-user and lowest privilege.
96
+
97
+ ## Release architecture
98
+
99
+ The Windows release uses one PyInstaller analysis and two onedir executables. An exact
100
+ first-party/distribution allowlist, Qt-component policy, component-to-notice policy, and
101
+ source-provenance lock fail closed on unknown staged content. The build produces a
102
+ portable ZIP, per-user installer, wheel, analysis/manifest/smoke receipts, and sorted
103
+ SHA-256 inventory from a hash-locked environment.
104
+
105
+ ## Verification
106
+
107
+ Tests cover the pure color/HDR core, workflow state machine, confirmation and recovery,
108
+ Windows API contracts, native-resource lifecycle, least-privilege boundary, GUI
109
+ truthfulness, Qt selection, frozen module closure, redistribution notices, and release
110
+ artifact construction. Publication additionally requires frozen offscreen smoke tests,
111
+ PE manifest inspection, component/source audits, and a clean install proof.
@@ -0,0 +1,12 @@
1
+ # Authors
2
+
3
+ ## Author and Maintainer
4
+
5
+ - Zain Dana Harper
6
+
7
+ ## AI Coding Contributor
8
+
9
+ - Claude Code
10
+
11
+ Zain Dana Harper reviews, tests, edits, and owns public release decisions,
12
+ security posture, and final claims.
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ ## v1.1.0 (2026-07-11)
4
+
5
+ - Updated GitHub Actions workflows to current checkout/setup-python majors.
6
+ - Added the documented `test` extra so `pip install -e ".[test]"` works.
7
+ - Normalized scanner-blocking dash punctuation in public docs and developer-facing strings.
8
+ - Project Telos presentation and operator-surface pass: README hero, brand assets under `docs/brand/`, cross-flagship navigation, and Current status / Operator surface blocks.
9
+ - Documented the operator surface across the PySide6 desktop workflow and read-only CLI.
10
+ - Relicensed to the FSL-1.1-MIT as part of Project Telos flagship promotion.
11
+ - Migrated the desktop runtime and Build UI integration to PySide6.
12
+ - Added the explicit Detect -> Method -> Preview -> Apply -> Verify -> Save/Report workflow.
13
+ - Consolidated display mutation behind one confirmation-bound Windows adapter; legacy
14
+ direct-action CLI commands are proposal-only in 1.1.
15
+ - Added immutable, SHA-256-bound apply plans, bounded inputs, prior-state capture,
16
+ compensating recovery, authoritative read-back, and concurrency/resource-lifecycle
17
+ gates.
18
+ - Removed automatic GUI, tray, guard, and startup actuator paths; packaged entry points
19
+ launch unelevated.
20
+ - Added measured/estimated/simulated/replayed/Not measured provenance throughout the GUI
21
+ and report paths; removed seeded or unsupported observations.
22
+ - Added read-only `doctor` diagnostics with stable JSON output.
23
+ - Added hash-locked Windows builds, exact frozen-module auditing, third-party notices and
24
+ source provenance, PE-manifest checks, per-user installer/portable packaging, and
25
+ frozen smoke/reproducibility verification.
26
+
27
+ ## v1.0.0 (2026-03-22)
28
+
29
+ ### Features
30
+ - **58-panel database** with DDC/CI recommendations for QD-OLED, WOLED, IPS, VA, Mini-LED, and RGB OLED panels
31
+ - **Sensorless calibration** using panel-specific characterization data and Bradford chromatic adaptation
32
+ - **Hardware calibration** via DDC/CI: brightness, contrast, RGB gain/offset, gamma
33
+ - **i1Display3 native USB driver** with CCMX spectral correction (44% dE improvement on QD-OLED)
34
+ - **3D LUT generation** (33x33x33) with 6 gamut mapping algorithms including CAM16 and Jzazbz
35
+ - **13 calibration targets**: Rec.709, DCI-P3, HDR10, Netflix SDR/HDR, EBU Grade 1, and more
36
+ - **12 verification patch sets** (287 patches): grayscale, saturation sweeps, SMPTE/EBU bars, skin tones
37
+ - **LUT export formats**: .cube, .3dl, .clf (ACES), .mga, .csp, ReShade, SpecialK, OBS, mpv, MadVR, ICC v4
38
+ - **CCSS/CCMX import** for community spectral corrections
39
+ - **CalibrationGuard** watchdog (15-second polling) prevents Windows from resetting calibration
40
+ - **DwmLutGUI integration** with automatic elevation for system-wide 3D LUT
41
+ - **PyQt6 GUI** with warm pastel theme, CIE chromaticity diagram, system tray, toast notifications
42
+ - **CLI** with 26 commands for headless calibration workflows
43
+
44
+ ### Platform Support
45
+ - Windows 10/11: Full support
46
+ - macOS: Planned (stubs exist)
47
+ - Linux: Planned (stubs exist)
48
+
49
+ ### Tests
50
+ - 197 tests passing
@@ -0,0 +1,10 @@
1
+ # Contributing
2
+
3
+ This repository is part of the Project Telos public surface. Keep changes small, tested, and easy for public users and developers to verify.
4
+
5
+ Before sending a change:
6
+
7
+ - Read `README.md` and any local `AGENTS.md` instructions.
8
+ - Run the narrowest test or verification command that covers the change.
9
+ - Keep examples, package metadata, and public claims aligned with current behavior.
10
+ - Do not commit secrets, `.env` files, private corpus material, or generated caches.
@@ -0,0 +1,110 @@
1
+ # Functional Source License, Version 1.1, MIT Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-MIT
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Zain Dana Harper
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the MIT license that is effective on the second anniversary of the date we make
91
+ the Software available. On or after that date, you may use the Software under
92
+ the MIT license, in which case the following will apply:
93
+
94
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
95
+ this software and associated documentation files (the "Software"), to deal in
96
+ the Software without restriction, including without limitation the rights to
97
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98
+ of the Software, and to permit persons to whom the Software is furnished to do
99
+ so, subject to the following conditions:
100
+
101
+ The above copyright notice and this permission notice shall be included in all
102
+ copies or substantial portions of the Software.
103
+
104
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110
+ SOFTWARE.
@@ -0,0 +1,31 @@
1
+ include LICENSE
2
+ include README.md
3
+ include ARCHITECTURE.md
4
+ include AUTHORS.md
5
+ include CHANGELOG.md
6
+ include CONTRIBUTING.md
7
+ include RELEASE_NOTES.md
8
+ include SECURITY.md
9
+ include USAGE.md
10
+ include pyproject.toml
11
+ include calibrate-pro.spec
12
+
13
+ recursive-include calibrate_pro *.py *.ico *.png
14
+ recursive-include tests *.py *.json
15
+ recursive-include packaging *.json *.lock *.in *.py
16
+ recursive-include scripts *.py *.ps1
17
+ recursive-include installer *.iss
18
+ recursive-include THIRD_PARTY_LICENSES *
19
+ recursive-include dwm_lut *
20
+ recursive-include docs *
21
+ recursive-include examples *.py
22
+ recursive-include .github *.yml *.yaml
23
+
24
+ global-exclude *.pyc
25
+ global-exclude __pycache__
26
+ prune build
27
+ prune dist
28
+ prune release
29
+ prune .mypy_cache
30
+ prune .pytest_cache
31
+ prune .ruff_cache