quant1x 0.7.62.dev2__tar.gz → 0.7.85__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 (361) hide show
  1. quant1x-0.7.85/.githooks/commit-msg +60 -0
  2. quant1x-0.7.85/.githooks/commit_msg_check.py +198 -0
  3. quant1x-0.7.85/.githooks/pre-commit +45 -0
  4. quant1x-0.7.85/.githooks/text_check.py +94 -0
  5. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.gitignore +7 -1
  6. {quant1x-0.7.62.dev2/.vscode → quant1x-0.7.85/.vscode-default}/c_cpp_properties.json +1 -1
  7. {quant1x-0.7.62.dev2/.vscode → quant1x-0.7.85/.vscode-default}/settings.json +54 -29
  8. quant1x-0.7.85/.vscode-macos/settings.json +11 -0
  9. quant1x-0.7.85/.vscode-windows/launch.json +12 -0
  10. quant1x-0.7.85/.vscode-windows/settings.json +19 -0
  11. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/AGENTS.md +68 -0
  12. quant1x-0.7.85/CHANGELOG.md +2946 -0
  13. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/CMakeLists.txt +80 -9
  14. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/Cargo.lock +534 -699
  15. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/Cargo.toml +14 -3
  16. quant1x-0.7.85/PKG-INFO +575 -0
  17. quant1x-0.7.85/README.md +526 -0
  18. quant1x-0.7.85/assets/icons/android/ic_launcher-playstore.png +0 -0
  19. quant1x-0.7.85/assets/icons/android/mipmap-hdpi/ic_launcher.png +0 -0
  20. quant1x-0.7.85/assets/icons/android/mipmap-mdpi/ic_launcher.png +0 -0
  21. quant1x-0.7.85/assets/icons/android/mipmap-xhdpi/ic_launcher.png +0 -0
  22. quant1x-0.7.85/assets/icons/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  23. quant1x-0.7.85/assets/icons/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  24. quant1x-0.7.85/assets/icons/icon-1024.png +0 -0
  25. quant1x-0.7.85/assets/icons/ios/Icon-App-1024x1024.png +0 -0
  26. quant1x-0.7.85/assets/icons/ios/Icon-App-20x20@1x.png +0 -0
  27. quant1x-0.7.85/assets/icons/ios/Icon-App-20x20@2x.png +0 -0
  28. quant1x-0.7.85/assets/icons/ios/Icon-App-20x20@3x.png +0 -0
  29. quant1x-0.7.85/assets/icons/ios/Icon-App-29x29@1x.png +0 -0
  30. quant1x-0.7.85/assets/icons/ios/Icon-App-29x29@2x.png +0 -0
  31. quant1x-0.7.85/assets/icons/ios/Icon-App-29x29@3x.png +0 -0
  32. quant1x-0.7.85/assets/icons/ios/Icon-App-40x40@2x.png +0 -0
  33. quant1x-0.7.85/assets/icons/ios/Icon-App-40x40@3x.png +0 -0
  34. quant1x-0.7.85/assets/icons/ios/Icon-App-60x60@2x.png +0 -0
  35. quant1x-0.7.85/assets/icons/ios/Icon-App-60x60@3x.png +0 -0
  36. quant1x-0.7.85/assets/icons/ios/Icon-App-76x76@1x.png +0 -0
  37. quant1x-0.7.85/assets/icons/ios/Icon-App-76x76@2x.png +0 -0
  38. quant1x-0.7.85/assets/icons/ios/Icon-App-83.5x83.5@2x.png +0 -0
  39. quant1x-0.7.85/assets/icons/macos/icon_128x128.png +0 -0
  40. quant1x-0.7.85/assets/icons/macos/icon_128x128@2x.png +0 -0
  41. quant1x-0.7.85/assets/icons/macos/icon_16x16.png +0 -0
  42. quant1x-0.7.85/assets/icons/macos/icon_16x16@2x.png +0 -0
  43. quant1x-0.7.85/assets/icons/macos/icon_256x256.png +0 -0
  44. quant1x-0.7.85/assets/icons/macos/icon_256x256@2x.png +0 -0
  45. quant1x-0.7.85/assets/icons/macos/icon_32x32.png +0 -0
  46. quant1x-0.7.85/assets/icons/macos/icon_32x32@2x.png +0 -0
  47. quant1x-0.7.85/assets/icons/macos/icon_512x512.png +0 -0
  48. quant1x-0.7.85/assets/icons/macos/icon_512x512@2x.png +0 -0
  49. quant1x-0.7.85/assets/icons/web/android-chrome-192x192.png +0 -0
  50. quant1x-0.7.85/assets/icons/web/android-chrome-512x512.png +0 -0
  51. quant1x-0.7.85/assets/icons/web/apple-touch-icon.png +0 -0
  52. quant1x-0.7.85/assets/icons/web/favicon-16x16.png +0 -0
  53. quant1x-0.7.85/assets/icons/web/favicon-32x32.png +0 -0
  54. quant1x-0.7.85/assets/icons/web/favicon-64x64.png +0 -0
  55. quant1x-0.7.85/assets/icons/web/favicon-96x96.png +0 -0
  56. quant1x-0.7.85/assets/icons/web/favicon.ico +0 -0
  57. quant1x-0.7.85/assets/icons/web/mstile-150x150.png +0 -0
  58. quant1x-0.7.85/assets/icons/web/site.webmanifest +19 -0
  59. quant1x-0.7.85/assets/icons/windows/app-256.png +0 -0
  60. quant1x-0.7.85/assets/icons/windows/app.ico +0 -0
  61. quant1x-0.7.85/logo.png +0 -0
  62. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/main.go +1 -1
  63. quant1x-0.7.85/mvnw +227 -0
  64. quant1x-0.7.85/mvnw.cmd +211 -0
  65. quant1x-0.7.85/pom.xml +88 -0
  66. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/pyproject.toml +10 -2
  67. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/_version.py +3 -3
  68. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/bits.py +4 -0
  69. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/asset_class.py +1 -1
  70. quant1x-0.7.85/quant1x/distributed/__init__.py +4 -0
  71. quant1x-0.7.85/quant1x/distributed/id/FileStateStore.java +145 -0
  72. quant1x-0.7.85/quant1x/distributed/id/Generator.java +46 -0
  73. quant1x-0.7.85/quant1x/distributed/id/HLC.java +155 -0
  74. quant1x-0.7.85/quant1x/distributed/id/Id.java +78 -0
  75. quant1x-0.7.85/quant1x/distributed/id/Option.java +57 -0
  76. quant1x-0.7.85/quant1x/distributed/id/PersistentState.java +35 -0
  77. quant1x-0.7.85/quant1x/distributed/id/README.md +235 -0
  78. quant1x-0.7.85/quant1x/distributed/id/StateStore.java +10 -0
  79. quant1x-0.7.85/quant1x/distributed/id/__init__.py +48 -0
  80. quant1x-0.7.85/quant1x/distributed/id/generator.py +74 -0
  81. quant1x-0.7.85/quant1x/distributed/id/hlc.py +109 -0
  82. quant1x-0.7.85/quant1x/distributed/id/id.py +83 -0
  83. quant1x-0.7.85/quant1x/distributed/id/option.py +80 -0
  84. quant1x-0.7.85/quant1x/distributed/id/queue.py +125 -0
  85. quant1x-0.7.85/quant1x/distributed/id/state_store.py +435 -0
  86. quant1x-0.7.85/quant1x/distributed/id/tests.py +306 -0
  87. quant1x-0.7.85/quant1x/id/id128/FileStateStore.java +279 -0
  88. quant1x-0.7.85/quant1x/id/id128/Generator.java +48 -0
  89. quant1x-0.7.85/quant1x/id/id128/HLC.java +219 -0
  90. quant1x-0.7.85/quant1x/id/id128/Id.java +88 -0
  91. quant1x-0.7.85/quant1x/id/id128/Option.java +99 -0
  92. quant1x-0.7.85/quant1x/id/id128/PersistentState.java +56 -0
  93. quant1x-0.7.85/quant1x/id/id128/README.md +387 -0
  94. quant1x-0.7.85/quant1x/id/id128/StateStore.java +36 -0
  95. quant1x-0.7.85/quant1x/id/id128/Uint128.java +284 -0
  96. quant1x-0.7.85/quant1x/id/id128/__init__.py +28 -0
  97. quant1x-0.7.85/quant1x/id/id128/generator.py +23 -0
  98. quant1x-0.7.85/quant1x/id/id128/hlc.py +103 -0
  99. quant1x-0.7.85/quant1x/id/id128/id.py +38 -0
  100. quant1x-0.7.85/quant1x/id/id128/id_test.py +93 -0
  101. quant1x-0.7.85/quant1x/id/id128/option.py +65 -0
  102. quant1x-0.7.85/quant1x/id/id128/state_store.py +274 -0
  103. quant1x-0.7.85/quant1x/id/id128/uint128.py +105 -0
  104. quant1x-0.7.85/quant1x/id/id64/ByteIO.java +59 -0
  105. quant1x-0.7.85/quant1x/id/id64/FileStateStore.java +272 -0
  106. quant1x-0.7.85/quant1x/id/id64/Generator.java +60 -0
  107. quant1x-0.7.85/quant1x/id/id64/HLC.java +202 -0
  108. quant1x-0.7.85/quant1x/id/id64/Id.java +94 -0
  109. quant1x-0.7.85/quant1x/id/id64/Option.java +97 -0
  110. quant1x-0.7.85/quant1x/id/id64/PersistentState.java +53 -0
  111. quant1x-0.7.85/quant1x/id/id64/README.md +246 -0
  112. quant1x-0.7.85/quant1x/id/id64/StateStore.java +36 -0
  113. quant1x-0.7.85/quant1x/id/id64/__init__.py +31 -0
  114. quant1x-0.7.85/quant1x/id/id64/generator.py +41 -0
  115. quant1x-0.7.85/quant1x/id/id64/hlc.py +114 -0
  116. quant1x-0.7.85/quant1x/id/id64/id.py +58 -0
  117. quant1x-0.7.85/quant1x/id/id64/id_test.py +163 -0
  118. quant1x-0.7.85/quant1x/id/id64/option.py +108 -0
  119. quant1x-0.7.85/quant1x/id/id64/state_store.py +267 -0
  120. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/regime/plot_results.py +4 -0
  121. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/regime/regime_switching_framework.py +4 -0
  122. quant1x-0.7.85/quant1x/runtime/__init__.py +0 -0
  123. quant1x-0.7.85/quant1x/runtime/ringbuffer.md +179 -0
  124. quant1x-0.7.85/quant1x/runtime/ringbuffer.py +210 -0
  125. quant1x-0.7.85/quant1x/runtime/ringbuffer_test.py +81 -0
  126. quant1x-0.7.85/quant1x.egg-info/PKG-INFO +575 -0
  127. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/SOURCES.txt +108 -6
  128. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/scm_file_list.json +186 -8
  129. quant1x-0.7.85/quant1x.egg-info/scm_version.json +8 -0
  130. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/rust-toolchain.toml +1 -1
  131. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/vcpkg.json +23 -13
  132. quant1x-0.7.62.dev2/CHANGELOG.md +0 -2435
  133. quant1x-0.7.62.dev2/PKG-INFO +0 -630
  134. quant1x-0.7.62.dev2/README.md +0 -583
  135. quant1x-0.7.62.dev2/logo.png +0 -0
  136. quant1x-0.7.62.dev2/quant1x/base/cache/market.dat +0 -4
  137. quant1x-0.7.62.dev2/quant1x/runtime/ringbuffer.md +0 -79
  138. quant1x-0.7.62.dev2/quant1x.cer +0 -0
  139. quant1x-0.7.62.dev2/quant1x.egg-info/PKG-INFO +0 -630
  140. quant1x-0.7.62.dev2/quant1x.egg-info/scm_version.json +0 -8
  141. quant1x-0.7.62.dev2/quant1x.pfx +0 -0
  142. quant1x-0.7.62.dev2/requirements.txt +0 -34
  143. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.clang-format +0 -0
  144. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.clang-tidy +0 -0
  145. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.clock_state +0 -0
  146. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.editorconfig +0 -0
  147. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/.gitattributes +0 -0
  148. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/CONTRIBUTING.md +0 -0
  149. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/LICENSE +0 -0
  150. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/MANIFEST.in +0 -0
  151. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/b2c.py +0 -0
  152. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/labs/akshare.ipynb +0 -0
  153. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/labs/qlib.ipynb +0 -0
  154. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/labs/quant1x.ipynb +0 -0
  155. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/main.cpp +0 -0
  156. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/main.py +0 -0
  157. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/main.rs +0 -0
  158. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/chips.proto +0 -0
  159. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/snapshot.capnp +0 -0
  160. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/snapshot.capnp.c++ +0 -0
  161. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/test-snapshot.py +0 -0
  162. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/trans.proto +0 -0
  163. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/proto/xdxr.proto +0 -0
  164. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/publish.bat +0 -0
  165. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/publish.ps1 +0 -0
  166. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/publish.sh +0 -0
  167. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/__init__.py +0 -0
  168. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/__init__.py +0 -0
  169. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/clock.py +0 -0
  170. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/dataclass_utils.py +0 -0
  171. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/embed.go.copy +0 -0
  172. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/except.py +0 -0
  173. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/filesystem.py +0 -0
  174. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/numeric.md +0 -0
  175. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/numeric.py +0 -0
  176. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/pattern.py +0 -0
  177. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/singleton.py +0 -0
  178. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/strings.md +0 -0
  179. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/strings.py +0 -0
  180. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/system.py +0 -0
  181. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/base/time.py +0 -0
  182. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/build-info.h.in +0 -0
  183. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/config/__init__.py +0 -0
  184. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/config/config.py +0 -0
  185. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/__init__.py +0 -0
  186. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/__init__.py +0 -0
  187. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/em/em_dividend.py +0 -0
  188. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/__init__.py +0 -0
  189. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/_constants.py +0 -0
  190. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/bar.py +0 -0
  191. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/bar_raw.py +0 -0
  192. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/client.py +0 -0
  193. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/command.py +0 -0
  194. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/config.py +0 -0
  195. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/datasource.py +0 -0
  196. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/financial_report.py +0 -0
  197. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/helpers.py +0 -0
  198. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/instruments.py +0 -0
  199. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/__init__.py +0 -0
  200. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/auction.py +0 -0
  201. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/ext/__init__.py +0 -0
  202. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/ext/ext-category.md +0 -0
  203. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/ext/hk_f10.py +0 -0
  204. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/ext/xdxr_hkex.py +0 -0
  205. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/fund.py +0 -0
  206. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/__init__.py +0 -0
  207. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/block.py +0 -0
  208. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/block_meta.py +0 -0
  209. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/finance_info.py +0 -0
  210. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/heartbeat.py +0 -0
  211. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/hello.py +0 -0
  212. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/minute_time.py +0 -0
  213. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/security_bars.py +0 -0
  214. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/security_count.py +0 -0
  215. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/security_list.py +0 -0
  216. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/security_quote.md +0 -0
  217. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/security_quote.py +0 -0
  218. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/transaction.py +0 -0
  219. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/level1/std/xdxr_info.py +0 -0
  220. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/market.py +0 -0
  221. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/money.py +0 -0
  222. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/notice.py +0 -0
  223. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/protocol.py +0 -0
  224. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/sector.py +0 -0
  225. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/share_holder.py +0 -0
  226. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/trans.py +0 -0
  227. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/contrib/data/tdx/xdxr.py +0 -0
  228. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/core/__init__.py +0 -0
  229. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/core/base.py +0 -0
  230. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/core/decode.py +0 -0
  231. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/core/defaults.py +0 -0
  232. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/__init__.py +0 -0
  233. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/adapter.py +0 -0
  234. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/base.py +0 -0
  235. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/cache.py +0 -0
  236. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/datasource.py +0 -0
  237. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/f10.py +0 -0
  238. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/margin_trading.py +0 -0
  239. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/market.py +0 -0
  240. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/__init__.py +0 -0
  241. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/calendar.py +0 -0
  242. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/exchange.py +0 -0
  243. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/forex.py +0 -0
  244. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/frequency.py +0 -0
  245. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/fund.md +0 -0
  246. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/fund.py +0 -0
  247. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/instrument.py +0 -0
  248. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/layout.py +0 -0
  249. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/region.py +0 -0
  250. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/session.md +0 -0
  251. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/session.py +0 -0
  252. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/sina/__init__.py +0 -0
  253. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/sina/decoder.py +0 -0
  254. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/__init__.py +0 -0
  255. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/market_bse.py +0 -0
  256. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/market_hkex.py +0 -0
  257. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/market_sse.py +0 -0
  258. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/market_szse.py +0 -0
  259. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/market_usa.py +0 -0
  260. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/ticker_rules/rule.py +0 -0
  261. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/meta/timestamp.py +0 -0
  262. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/README.md +0 -0
  263. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/__init__.py +0 -0
  264. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/adjustment.md +0 -0
  265. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/adjustment.py +0 -0
  266. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/bar.md +0 -0
  267. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/bar.py +0 -0
  268. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/company.md +0 -0
  269. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/company.py +0 -0
  270. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/dividend.md +0 -0
  271. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/dividend.py +0 -0
  272. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/sector.md +0 -0
  273. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/sector.py +0 -0
  274. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/trade.md +0 -0
  275. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/schema/trade.py +0 -0
  276. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/status.py +0 -0
  277. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/storage/__init__.py +0 -0
  278. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/storage/csv.py +0 -0
  279. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/storage/storage.md +0 -0
  280. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/data/storage/storage.py +0 -0
  281. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/device.py +0 -0
  282. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/devp.py +0 -0
  283. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/__init__.py +0 -0
  284. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/README.md +0 -0
  285. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/cstruct/FORK.md +0 -0
  286. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/cstruct/LICENSE +0 -0
  287. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/cstruct/README.md +0 -0
  288. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/struc/LICENSE +0 -0
  289. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/binary/struc/README.md +0 -0
  290. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/json.md +0 -0
  291. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/encoding/yaml.py +0 -0
  292. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/__init__.py +0 -0
  293. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/f10.py +0 -0
  294. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/financial_report.py +0 -0
  295. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/notice.py +0 -0
  296. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/safety_score.py +0 -0
  297. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/factors/share_holder.py +0 -0
  298. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/formula/README-MyTT.md +0 -0
  299. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/formula/__init__.py +0 -0
  300. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/formula/formula.ipynb +0 -0
  301. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/formula/formula.py +0 -0
  302. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/formula/formula_plus.py +0 -0
  303. {quant1x-0.7.62.dev2/quant1x/runtime → quant1x-0.7.85/quant1x/id}/__init__.py +0 -0
  304. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/README.md +0 -0
  305. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/__init__.py +0 -0
  306. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/cdtd.md +0 -0
  307. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/cdtd.py +0 -0
  308. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/f89k.md +0 -0
  309. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/f89k.py +0 -0
  310. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/hjk.md +0 -0
  311. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/hjk.py +0 -0
  312. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/ma1x.md +0 -0
  313. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/ma1x.py +0 -0
  314. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/p2fb.md +0 -0
  315. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/p2fb.py +0 -0
  316. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/indicators/winner.md +0 -0
  317. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/__init__.py +0 -0
  318. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/connection_pool.md +0 -0
  319. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/connection_pool.py +0 -0
  320. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/csv-reader.LICENSE +0 -0
  321. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/csv-reader.md +0 -0
  322. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/endpoint.py +0 -0
  323. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/io/operation_handler.py +0 -0
  324. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/fpgrowth/README.md +0 -0
  325. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/fpgrowth/fp_growth.md +0 -0
  326. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/fpgrowth/fp_growth_example.py +0 -0
  327. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/learn/regime/README.md +0 -0
  328. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/log/__init__.py +0 -0
  329. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/log/logger.py +0 -0
  330. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/log4rs.yaml +0 -0
  331. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/net/__init__.py +0 -0
  332. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/net/conn.py +0 -0
  333. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/net/endpoint.py +0 -0
  334. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/net/handler.py +0 -0
  335. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/net/tcp_client_pool.py +0 -0
  336. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/network.py +0 -0
  337. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/proto/README.md +0 -0
  338. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/proto/security_info.proto +0 -0
  339. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/proto/snapshot.capnp.c++ +0 -0
  340. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/resources/README.md +0 -0
  341. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/resources/meta/tdxhy.inc +0 -0
  342. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/resources/meta/tdxzs.inc +0 -0
  343. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/resources/meta/tdxzs3.inc +0 -0
  344. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/runtime/once.py +0 -0
  345. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/runtime/scheduler.md +0 -0
  346. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/runtime/scheduler.py +0 -0
  347. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/ta/README.md +0 -0
  348. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/tools/inspect_blocks.py +0 -0
  349. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/types.py +0 -0
  350. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/util/SimHei.ttf +0 -0
  351. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/util/__init__.py +0 -0
  352. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/util/chart.py +0 -0
  353. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/util/font.py +0 -0
  354. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/util/util-font.ipynb +0 -0
  355. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x/version.py +0 -0
  356. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/dependency_links.txt +0 -0
  357. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/not-zip-safe +0 -0
  358. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/requires.txt +0 -0
  359. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/quant1x.egg-info/top_level.txt +0 -0
  360. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/setup.cfg +0 -0
  361. {quant1x-0.7.62.dev2 → quant1x-0.7.85}/test_loop.sh +0 -0
@@ -0,0 +1,60 @@
1
+ #!/bin/sh
2
+ # commit-msg 钩子:提交信息编码校验(非法 UTF-8 / GBK 乱码 → 拒绝提交)
3
+ # 校验逻辑见同目录 commit_msg_check.py
4
+ hook_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ run_check() {
6
+ # 优先使用 python / python3;在 Windows 环境下回退到 py -3
7
+ if command -v python >/dev/null 2>&1; then
8
+ python -V >/dev/null 2>&1
9
+ probe=$?
10
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
11
+ python "$hook_dir/commit_msg_check.py" "$1"
12
+ return $?
13
+ fi
14
+ fi
15
+ if command -v python3 >/dev/null 2>&1; then
16
+ python3 -V >/dev/null 2>&1
17
+ probe=$?
18
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
19
+ python3 "$hook_dir/commit_msg_check.py" "$1"
20
+ return $?
21
+ fi
22
+ fi
23
+ if command -v py >/dev/null 2>&1; then
24
+ py -3 -V >/dev/null 2>&1
25
+ probe=$?
26
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
27
+ py -3 "$hook_dir/commit_msg_check.py" "$1"
28
+ return $?
29
+ fi
30
+ fi
31
+ return 127
32
+ }
33
+
34
+ run_check "$1"
35
+ check_rc=$?
36
+ if [ "$check_rc" -eq 127 ]; then
37
+ echo "commit-msg 校验未通过:未找到可用 Python 解释器(python/python3/py -3)。" >&2
38
+ exit 1
39
+ fi
40
+ if [ "$check_rc" -ne 0 ]; then
41
+ echo "commit-msg 校验未通过,提交已中止。请修正提交信息后重试。" >&2
42
+ exit 1
43
+ fi
44
+
45
+ # 提交尾注/署名约束(仓库规则):
46
+ # - 禁止 Co-authored-by trailer
47
+ # - 禁止 Copilot/AI 署名(包含历史常见 noreply 地址)
48
+ msg_file="$1"
49
+ if [ -n "$msg_file" ] && [ -f "$msg_file" ]; then
50
+ if tr -d '\r' < "$msg_file" | grep -Eiq '^[[:space:]]*co-authored-by[[:space:]]*:'; then
51
+ echo "commit-msg 校验未通过:禁止 Co-authored-by trailer。" >&2
52
+ exit 1
53
+ fi
54
+ if tr -d '\r' < "$msg_file" | grep -Eiq 'copilot@users\.noreply\.github\.com|^[[:space:]]*(copilot|ai)[[:space:]]*(署名|signature)[[:space:]]*:'; then
55
+ echo "commit-msg 校验未通过:禁止 Copilot/AI 署名信息。" >&2
56
+ exit 1
57
+ fi
58
+ fi
59
+
60
+ exit 0
@@ -0,0 +1,198 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2026 Quant1X <wangfengxy@sina.cn>
3
+ # SPDX-License-Identifier: AGPL-3.0-only
4
+
5
+ """commit-msg 校验:提交信息编码完整性检查(拒绝乱码/损坏文本)。
6
+
7
+ Windows 下中文提交信息若经 GBK 命令行/控制台传递,会被错误转码并作为
8
+ “合法 UTF-8 的乱码文本”写入提交对象(历史上有 daa14be / 8e49a85 两例)。
9
+ 本脚本只做两类判断,全部基于编码事实,不维护任何“乱码特征字”黑名单:
10
+
11
+ 一、硬性检查(编码损坏的直接证据)
12
+ - 必须整体是合法 UTF-8;
13
+ - 不含 NUL 字节、替换符 U+FFFD、私有区字符(PUA)。
14
+ 这些都是正常输入不可能出现、只会由编码损坏产生的字符。
15
+
16
+ 二、round-trip 反推(乱码检测主逻辑)
17
+ 乱码的产生链是确定的:
18
+ 原始 UTF-8 字节流 → 被按编码 E 误读(得到“乱码字符”)
19
+ → 再以 UTF-8 存储(得到我们看到的文本)
20
+ 因此把待检文本按 E 重新编码、再按 UTF-8 解码,若还原出的文本
21
+ “与原文不同且以汉字为主”,即可确认它是 E 误读的产物:
22
+ text.encode(E).decode('utf-8') → 原始中文
23
+ CANDIDATES 列出常见误读链(GB18030/CP1252/Latin-1/Shift_JIS/
24
+ EUC-KR/KOI8-R 等)。将来出现“UTF-8 被当作编码 X 读取”的新形态,
25
+ 只需在 CANDIDATES 增补一行,无需维护字符表。
26
+
27
+ 误报分析(为何“还原出汉字”是强信号):
28
+ - 正常中文文本按 GBK/GB18030 整体编码后,字节流几乎必然无法构成
29
+ 合法 UTF-8(单字双字节落点不在 UTF-8 合法区间内,序列连续性亦
30
+ 不成立),解码必然失败;即便以 errors='replace' 宽容扫描,GBK
31
+ 字节偶合出的 UTF-8 片段也只会落在 Latin 区(2 字节 UTF-8 编码
32
+ 范围 U+0080..U+07FF 不含汉字),汉字必须由 3 字节 UTF-8 编码,
33
+ 这种连续偶合几乎不可能成串出现。因此“还原文本含 >= 2 个汉字”
34
+ 基本只可能来自真正的乱码。
35
+
36
+ 字节丢失处理:误读链若带丢字节(历史两例即如此),还原会以
37
+ errors='replace' 进行,丢失处产生 U+FFFD。此时用 “FFFD 数 <= 还原
38
+ 汉字数” 约束:真乱码还原后汉字是主体、FFFD 只是零星丢失位;
39
+ 正常文本偶合还原出的汉字极少而 FFFD 占绝对多数,二者可明确区分。
40
+
41
+ 用法:
42
+ python commit_msg_check.py <commit-msg-file>
43
+ python commit_msg_check.py --debug <commit-msg-file> # 诊断模式
44
+ 返回 0 通过;非 0 拒绝(信息输出到 stderr)。
45
+
46
+ --debug 模式:对每个 CANDIDATE 打印 round-trip 诊断(encode 结果、
47
+ 解码模式、还原汉字数 / FFFD 数、是否命中),便于排查“新出现的乱码
48
+ 形态应归入哪条误读链”。
49
+ """
50
+ import re
51
+ import sys
52
+
53
+ # 误读链候选,按仓库环境(Windows/中文)常见度排序;每条注明典型场景,
54
+ # 日后按“实际观测到的新乱码形态”增补即可:
55
+ # gb18030 Windows 简体中文环境把 UTF-8 字节流按 GBK/CP936 读取后再以
56
+ # UTF-8 存储 —— 本仓库历史乱码(daa14be / 8e49a85)即此链;
57
+ # GB18030 是 GBK 的超集,覆盖其全部单/双字节形态
58
+ # cp1252 Windows 拉丁环境按 CP1252 读取 UTF-8(“é…” 型 mojibake)
59
+ # latin-1 逐字节无损映射的 ISO-8859-1,覆盖 cp1252 未包含的 0x80-0x9F 形态
60
+ # shift_jis 日文环境按 Shift_JIS/CP932 读取 UTF-8
61
+ # euc_kr 韩文环境按 EUC-KR 读取 UTF-8
62
+ # koi8_r 俄文/西里尔环境按 KOI8-R 读取 UTF-8
63
+ CANDIDATES = [
64
+ ("gb18030", "UTF-8 被按 GBK/GB18030 误读"),
65
+ ("cp1252", "UTF-8 被按 CP1252 误读"),
66
+ ("latin-1", "UTF-8 被按 Latin-1(ISO-8859-1) 误读"),
67
+ ("shift_jis", "UTF-8 被按 Shift_JIS/CP932 误读"),
68
+ ("euc_kr", "UTF-8 被按 EUC-KR 误读"),
69
+ ("koi8_r", "UTF-8 被按 KOI8-R 误读"),
70
+ ]
71
+
72
+ # 汉字集合(CJK 扩展 A + 统一表意 + 兼容表意)—— 还原文本“汉字量”判断用
73
+ _HAN_RE = re.compile(r"[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]")
74
+
75
+
76
+ def _roundtrip(enc, text):
77
+ """单候选 round-trip 反推。encode 失败(该编码不可能误读出此文本)返回 None。"""
78
+ try:
79
+ raw = text.encode(enc)
80
+ except UnicodeEncodeError:
81
+ return None
82
+ try:
83
+ recovered = raw.decode("utf-8")
84
+ mode = "strict"
85
+ loss = 0
86
+ except UnicodeDecodeError:
87
+ recovered = raw.decode("utf-8", errors="replace")
88
+ mode = "replace"
89
+ loss = recovered.count("\ufffd")
90
+ return {
91
+ "recovered": recovered,
92
+ "mode": mode,
93
+ "loss": loss,
94
+ "han": len(_HAN_RE.findall(recovered)),
95
+ }
96
+
97
+
98
+ def detect_mojibake(text):
99
+ """命中返回 (encoding, label, recovered),否则 None。"""
100
+ for enc, label in CANDIDATES:
101
+ r = _roundtrip(enc, text)
102
+ if r is None or r["recovered"] == text:
103
+ continue
104
+ if r["han"] >= 2 and r["loss"] <= r["han"]:
105
+ return enc, label, r["recovered"]
106
+ return None
107
+
108
+
109
+ def _clean_preview(text, limit=72):
110
+ out = []
111
+ for ch in text:
112
+ if ch == "\ufffd":
113
+ continue
114
+ o = ord(ch)
115
+ if o < 32 and ch not in "\t\n":
116
+ continue
117
+ out.append(ch)
118
+ return "".join(out)[:limit]
119
+
120
+
121
+ def _debug_report(text, valid_utf8):
122
+ sys.stderr.write("commit-msg 校验 --debug:\n")
123
+ if not valid_utf8:
124
+ sys.stderr.write(" 文本非合法 UTF-8,round-trip 检测跳过(硬性检查已拒绝)\n")
125
+ return
126
+ for enc, label in CANDIDATES:
127
+ r = _roundtrip(enc, text)
128
+ if r is None:
129
+ sys.stderr.write(" %-9s %s\n" % (enc, "encode 失败——不可能为该编码误读产物"))
130
+ continue
131
+ same = r["recovered"] == text
132
+ hit = (not same and r["han"] >= 2 and r["loss"] <= r["han"])
133
+ verdict = "命中" if hit else ("还原=原文" if same else "未命中")
134
+ sys.stderr.write(
135
+ " %-9s %s decode=%s han=%d loss=%d %s\n"
136
+ % (enc, r["mode"], verdict, r["han"], r["loss"], label)
137
+ )
138
+ if hit:
139
+ sys.stderr.write(" 反推还原:%s\n" % _clean_preview(r["recovered"]))
140
+
141
+
142
+ def check(path, debug=False):
143
+ with open(path, "rb") as f:
144
+ raw = f.read()
145
+ problems = []
146
+
147
+ if b"\x00" in raw:
148
+ problems.append("包含 NUL 字节")
149
+
150
+ try:
151
+ text = raw.decode("utf-8")
152
+ valid_utf8 = True
153
+ except UnicodeDecodeError as e:
154
+ problems.append("不是合法 UTF-8:%s" % e)
155
+ text = raw.decode("utf-8", errors="replace")
156
+ valid_utf8 = False
157
+
158
+ if "\ufffd" in text:
159
+ problems.append("含替换符 U+FFFD(编码损坏标记)")
160
+
161
+ if any("\ue000" <= ch <= "\uf8ff" for ch in text):
162
+ problems.append("含私有区字符 U+E000..U+F8FF(编码损坏迹象)")
163
+
164
+ if debug:
165
+ _debug_report(text, valid_utf8)
166
+
167
+ if valid_utf8:
168
+ hit = detect_mojibake(text)
169
+ if hit:
170
+ enc, label, recovered = hit
171
+ preview = _clean_preview(recovered)
172
+ problems.append(
173
+ "%s:round-trip 反推可还原为「%s%s」"
174
+ % (label, preview, "…" if len(recovered) > 72 else "")
175
+ )
176
+
177
+ if problems:
178
+ for p in problems:
179
+ sys.stderr.write("commit-msg 校验未通过:%s\n" % p)
180
+ sys.stderr.write(
181
+ "提示:Windows 下提交中文信息请走 UTF-8 文件方式,例如\n"
182
+ " git commit -F .git/commit-msg.tmp\n"
183
+ "不要把中文直接写在命令行 -m 参数里。\n"
184
+ )
185
+ return 1
186
+ return 0
187
+
188
+
189
+ if __name__ == "__main__":
190
+ args = sys.argv[1:]
191
+ debug = False
192
+ if args and args[0] == "--debug":
193
+ debug = True
194
+ args = args[1:]
195
+ if len(args) < 1:
196
+ sys.stderr.write("usage: commit_msg_check.py [--debug] <commit-msg-file>\n")
197
+ sys.exit(2)
198
+ sys.exit(check(args[0], debug=debug))
@@ -0,0 +1,45 @@
1
+ #!/bin/sh
2
+ # pre-commit 钩子:提交内容编码校验(新混入 BOM → 拒绝提交)
3
+ # 校验逻辑见同目录 text_check.py
4
+ hook_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ run_check() {
6
+ # 优先使用 python / python3;在 Windows 环境下回退到 py -3
7
+ if command -v python >/dev/null 2>&1; then
8
+ python -V >/dev/null 2>&1
9
+ probe=$?
10
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
11
+ python "$hook_dir/text_check.py"
12
+ return $?
13
+ fi
14
+ fi
15
+ if command -v python3 >/dev/null 2>&1; then
16
+ python3 -V >/dev/null 2>&1
17
+ probe=$?
18
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
19
+ python3 "$hook_dir/text_check.py"
20
+ return $?
21
+ fi
22
+ fi
23
+ if command -v py >/dev/null 2>&1; then
24
+ py -3 -V >/dev/null 2>&1
25
+ probe=$?
26
+ if [ "$probe" -ne 126 ] && [ "$probe" -ne 127 ]; then
27
+ py -3 "$hook_dir/text_check.py"
28
+ return $?
29
+ fi
30
+ fi
31
+ return 127
32
+ }
33
+
34
+ run_check
35
+ check_rc=$?
36
+ if [ "$check_rc" -eq 127 ]; then
37
+ echo "pre-commit 校验未通过:未找到可用 Python 解释器(python/python3/py -3)。" >&2
38
+ exit 1
39
+ fi
40
+ if [ "$check_rc" -ne 0 ]; then
41
+ echo "pre-commit 校验未通过,提交已中止。请去掉新混入的 BOM 后重试。" >&2
42
+ exit 1
43
+ fi
44
+
45
+ exit 0
@@ -0,0 +1,94 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2026 Quant1X <wangfengxy@sina.cn>
3
+ # SPDX-License-Identifier: AGPL-3.0-only
4
+
5
+ """pre-commit 校验:拦截混进本次提交内容的 BOM。
6
+
7
+ 仓库一律 UTF-8 无 BOM —— 规定见 AGENTS.md 的「文件编码与行尾约定」。这东西肉眼
8
+ 不可见,Markdown 预览里往往也不显示,靠事后自查容易漏,故在提交这道口子上堵住。
9
+
10
+ **为什么只查新增行,不扫整个文件**:CHANGELOG.md 现存 17 处行首 U+FEFF,是历史
11
+ 事实,已明确不予追溯修正。若钩子扫全文件,那么每改动一次该文件都会被拦下 ——
12
+ 规矩一旦扰民,最后的结果只会是被 `--no-verify` 绕过去。故这里只检查**本次提交
13
+ 新引入的行**:既往的不良留在原地不动,新的一个也不许进来。
14
+
15
+ **为什么不查 CRLF**:行尾已由 `.gitattributes` 的 `text eol=lf` 兜住 —— 实测带
16
+ CRLF 的文件 add 进暂存区时 git 就归一成了 LF,并打印 `CRLF will be replaced by
17
+ LF`。钩子重复那一层只是徒增啰嗦,故不管。
18
+
19
+ **如何取新增行**:`git diff --cached -U0 -- <文件>`,取以 `+` 开头且非 `+++`
20
+ 文件头的那些行。附带的好处是:二进制文件 git 只输出 `Binary files ... differ`
21
+ 而不产生 `+` 行,故无需另行判断是否二进制。
22
+
23
+ **例外**:`.bat` / `.cmd` 整体豁免 —— 它们是 Windows 批处理,形态自成一格。
24
+
25
+ 用法:
26
+ python text_check.py
27
+ 返回 0 通过;非 0 拒绝(信息输出到 stderr)。
28
+ """
29
+ import subprocess
30
+ import sys
31
+
32
+ BOM = b"\xef\xbb\xbf"
33
+
34
+ # Windows 批处理整体豁免, 见 AGENTS.md 的文件编码与行尾约定
35
+ EXEMPT_SUFFIXES = (".bat", ".cmd")
36
+
37
+
38
+ def _git(args, binary=False):
39
+ """执行 git 子命令。失败即抛, 让钩子明确报错而不是静默放过。"""
40
+ proc = subprocess.run(
41
+ ["git"] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE
42
+ )
43
+ if proc.returncode != 0:
44
+ raise RuntimeError(
45
+ "git %s 失败: %s" % (" ".join(args), proc.stderr.decode("utf-8", "replace"))
46
+ )
47
+ return proc.stdout if binary else proc.stdout.decode("utf-8", "replace")
48
+
49
+
50
+ def staged_files():
51
+ """本次待提交(新增/复制/修改)的文件列表; -z 分隔, 文件名带空格也拆不开。"""
52
+ out = _git(["diff", "--cached", "--name-only", "-z", "--diff-filter=ACM"])
53
+ return [f for f in out.split("\0") if f]
54
+
55
+
56
+ def added_lines(path):
57
+ """本次提交在该文件里新增的行(字节), 去掉 diff 的 `+` 号与 `+++` 文件头。"""
58
+ raw = _git(["diff", "--cached", "-U0", "--", path], binary=True)
59
+ return [
60
+ line[1:]
61
+ for line in raw.split(b"\n")
62
+ if line.startswith(b"+") and not line.startswith(b"+++")
63
+ ]
64
+
65
+
66
+ def scan(path):
67
+ """本次新增行里的 BOM 数。"""
68
+ return sum(line.count(BOM) for line in added_lines(path))
69
+
70
+
71
+ def main():
72
+ offenders = []
73
+ for path in staged_files():
74
+ if path.lower().endswith(EXEMPT_SUFFIXES):
75
+ continue
76
+ bom = scan(path)
77
+ if bom:
78
+ offenders.append((path, bom))
79
+
80
+ if not offenders:
81
+ return 0
82
+
83
+ sys.stderr.write("pre-commit 校验未通过:下列文件**本次新增的行**混进了 BOM\n\n")
84
+ for path, bom in offenders:
85
+ sys.stderr.write(" %s BOM=%d\n" % (path, bom))
86
+ sys.stderr.write(
87
+ "\nU+FEFF 多半是某次编辑把自带 BOM 的一段文本拼接进来的 —— 它肉眼看不见,\n"
88
+ "所见只是 `- ` 与正文之间多了个位置。修法见 AGENTS.md 的「文件编码与行尾约定」。\n"
89
+ )
90
+ return 1
91
+
92
+
93
+ if __name__ == "__main__":
94
+ sys.exit(main())
@@ -20,6 +20,9 @@ dist/
20
20
  *.egg-info/
21
21
 
22
22
  *.png
23
+ # 应用与网站图标是交付物, 需入库 (由 scripts/gen_icons.py 从 logo.png 生成)
24
+ !assets/icons/**/*.png
25
+
23
26
  *.pkl
24
27
 
25
28
  #visual studio
@@ -42,7 +45,10 @@ target/
42
45
  .env
43
46
 
44
47
  # vscode
45
- .vscode/launch.json
48
+ .vscode/
46
49
 
47
50
  # setuptools_scm generated version file
48
51
  _version.py
52
+
53
+ # Maven Wrapper 下载缓存(首次运行自动下载,不入库)
54
+ .mvn/
@@ -7,4 +7,4 @@
7
7
  }
8
8
  ],
9
9
  "version": 4
10
- }
10
+ }
@@ -1,13 +1,58 @@
1
1
  {
2
+ // ===== 编辑器与字体 (VS Code 内置) =====
3
+ "editor.fontFamily": "'Source Code Pro', 'Courier New', monospace",
4
+ "editor.fontVariations": false,
5
+ "editor.inlayHints.fontFamily": "",
6
+ "editor.inlineSuggest.fontFamily": "'Source Code Pro', 'Courier New', monospace",
7
+ "debug.console.fontFamily": "'Source Code Pro', 'Courier New', monospace",
8
+ "chat.editor.fontFamily": "default",
9
+ "chat.fontFamily": "default",
10
+
11
+ // ===== 终端 (VS Code 内置) =====
12
+ "terminal.integrated.fontFamily": "'FiraCode Nerd Font Mono', 'Courier New', monospace",
13
+ "terminal.integrated.scrollback": 10000,
14
+
15
+ // ===== Python =====
16
+ "python.analysis.autoImportCompletions": true,
17
+ "python.envFile": "${workspaceFolder}/.env",
18
+
19
+ // ===== Go =====
20
+ "go.diagnostic.vulncheck": "Imports",
21
+
22
+ // ===== CMake =====
23
+ "cmake.launchBehavior": "reuseTerminal",
24
+ "cmake.buildDirectory": "${workspaceFolder}/build",
25
+ "cmake.configureSettings": {
26
+ "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
27
+ "CMAKE_BUILD_TYPE": "Debug"
28
+ },
29
+ // "cmake.configureArgs": [
30
+ // "-DVCPKG_PREFER_SYSTEM_LIBS=OFF",
31
+ // "-DVCPKG_MANIFEST_MODE=OFF"
32
+ // ],
33
+ "cmake.buildArgs": [
34
+ "--config",
35
+ "Debug"
36
+ ],
37
+
38
+ // ===== vcpkg =====
39
+ // triplet 与工具链路径随平台, 见 .vscode-windows / .vscode-macos
40
+ //"vcpkg.general.enable": true,
41
+ //"vcpkg.target.useStaticLib": false,
42
+ //"vcpkg.target.installDependencies": true,
43
+ //"vcpkg.target.preferSystemLibs": false,
44
+ //"vcpkg.target.useManifest": false,
45
+
46
+ // ===== C++ 测试 (C++ TestMate) =====
2
47
  "testMate.cpp.test.advancedExecutables": [
3
48
  {
4
- // macOS / Linux: executables produced by CMake usually have no extension
49
+ // macOS / Linux: 可执行文件通常无扩展名
5
50
  "pattern": "build/tests/catch2-*",
6
51
  "cwd": "${workspaceFolder}",
7
52
  "env": {}
8
53
  },
9
54
  {
10
- // Windows: keep the existing .exe pattern
55
+ // Windows: 保留 .exe 模式
11
56
  "pattern": "build/tests/catch2-*.exe",
12
57
  "cwd": "${workspaceFolder}",
13
58
  "env": {}
@@ -25,7 +70,7 @@
25
70
  "ASAN_OPTIONS": "detect_leaks=1",
26
71
  "LSAN_OPTIONS": "suppressions=leaksanitizer.supp",
27
72
  "DYLD_LIBRARY_PATH": "${command:cmake.buildDirectory}/lib"
28
- },
73
+ }
29
74
  },
30
75
  "win32": {
31
76
  "type": "cppdbg"
@@ -34,33 +79,13 @@
34
79
  "program": "${exec}",
35
80
  "args": "${argsArray}",
36
81
  "cwd": "${command:cmake.launchTargetDirectory}",
37
- "sourceFileMap": "${sourceFileMapObj}",
82
+ "sourceFileMap": "${sourceFileMapObj}"
38
83
  },
39
84
  "testMate.cpp.debug.noThrow": false,
40
- "python.analysis.autoImportCompletions": true,
41
- "python.envFile": "${workspaceFolder}/.env",
42
- "cmake.buildDirectory": "${workspaceFolder}/build",
43
- "cmake.configureSettings": {
44
- "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
45
- "CMAKE_BUILD_TYPE": "Debug"
46
- },
47
- "cmake.buildArgs": [
48
- "--config",
49
- "Debug"
50
- ],
51
- "cmake.launchBehavior": "reuseTerminal",
52
- "terminal.integrated.fontFamily": "'FiraCode Nerd Font Mono', 'Courier New', monospace",
53
- "debug.console.fontFamily": "'Source Code Pro', 'Courier New', monospace",
54
- "editor.inlayHints.fontFamily": "",
55
- "editor.fontVariations": false,
56
- "editor.fontFamily": "'Source Code Pro', 'Courier New', monospace",
57
- "editor.inlineSuggest.fontFamily": "'Source Code Pro', 'Courier New', monospace",
58
- "chat.editor.fontFamily": "default",
59
- "chat.fontFamily": "default",
60
- "terminal.integrated.scrollback": 10000,
61
- "go.diagnostic.vulncheck": "Imports",
85
+
86
+ // ===== 代码运行 (Code Runner) =====
62
87
  "code-runner.executorMap": {
63
- "python": "python scripts/run_module.py $fullFileName"
88
+ "python": "python scripts/run_module.py $fullFileName"
64
89
  },
65
- "code-runner.runInTerminal": true,
66
- }
90
+ "code-runner.runInTerminal": true
91
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ // ===== Python =====
3
+ "python-envs.defaultEnvManager": "ms-python.python:pyenv",
4
+
5
+ // ===== CMake =====
6
+ // CMakeLists.txt 在 DEFINED ENV{VCPKG_ROOT} 缺失时 FATAL_ERROR, 故显式给出根目录,
7
+ // 不依赖外部终端环境。
8
+ // "cmake.configureEnvironment": {
9
+ // "VCPKG_ROOT": "/Users/wangfeng/runtime/vcpkg"
10
+ // }
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "configurations": [
3
+ {
4
+ "type": "cmake",
5
+ "request": "launch",
6
+ "name": "Debug portfile(s)",
7
+ "cmakeDebugType": "external",
8
+ "pipeName": "\\\\.\\pipe\\vcpkg_ext_portfile_dbg",
9
+ "preLaunchTask": "Debug vcpkg commands"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ // ===== vcpkg =====
3
+ // CMakeLists.txt 在 DEFINED ENV{VCPKG_ROOT} 缺失时 FATAL_ERROR, 故显式给出根目录,
4
+ // 不依赖外部终端环境; 工具链文件由同一根目录推导。
5
+ //"vcpkg.general.vcpkgPath": "d:\\runtime\\vcpkg",
6
+ // "vcpkg.target.hostTriplet": "x64-mingw-static",
7
+ // "vcpkg.target.defaultTriplet": "x64-mingw-static",
8
+
9
+ // ===== CMake =====
10
+ // "cmake.configureEnvironment": {
11
+ // "VCPKG_ROOT": "d:\\runtime\\vcpkg"
12
+ // },
13
+ // "cmake.configureSettings": {
14
+ // "CMAKE_TOOLCHAIN_FILE": "d:\\runtime\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake"
15
+ // }
16
+
17
+ // triplet 由 CMakeLists.txt 按编译器判定并以 FORCE 写入缓存, 此处不再重复指定:
18
+ // MinGW/GNU -> x64-mingw-static, MSVC/Clang -> x64-windows-static
19
+ }
@@ -17,6 +17,9 @@
17
17
  - Go 实现必须位于功能子目录中,例如 `data/t1/`
18
18
  - Go 包名必须与目录名完全一致(如 `package t1`)
19
19
  - **禁止**为了"方便"合并 Go 文件到根目录
20
+ - Java 测试文件的 `package` 必须与 `tests/` 作为源码根目录时的目录层级一致;不应额外增加 `quant1x` 顶层包,但也不能省略 `tests` 根层级,例如 `tests/distributed/id` 对应 `package tests.distributed.id`
21
+ - 若 IDE/编译器提示 `The declared package "distributed.id" does not match the expected package "tests.distributed.id"`,这是错误配置;必须修正为 `tests` 目录根层级与 package 一致,并禁止在 Java 测试里人为多加 `quant1x.` 这一层
22
+ - 任何新增 Java 类/测试都必须遵循“模块目录 == package 层级(相对 tests 根目录)”的规则,避免出现 `quant1x.distributed.id`、`distributed.id` 这种与 `tests/` 根层级不一致的命名
20
23
 
21
24
  ## 三、命名规则
22
25
 
@@ -188,6 +191,71 @@ type Bar struct {
188
191
  - ❌ 在代码或提交信息中自行推断版本号
189
192
  - ❌ 修改 `CHANGELOG.md`、`pyproject.toml`、`Cargo.toml` 中的 `version` 字段
190
193
 
194
+ ## 提交信息规范
195
+
196
+ - Git commit 的主题和正文必须使用中文,准确说明本次变更内容。
197
+ - 提交信息不得自行添加版本号、Git Tag 或发布相关信息。
198
+ - 所有代码变更(新特性、Bug 修复、重构、测试、文档、性能优化等)必须在提交主题中显式标注涉及的开发语言,确保多语言语义一致的审计性。
199
+ - 主题必须采用统一模板:`<type>[<language>]:<summary>`。
200
+ - `<type>` 取值建议:`feat`(新特性)、`fix`(修复)、`refactor`(重构)、`test`(测试)、`perf`(性能)、`docs`(文档)、`chore`(例行维护)。
201
+ - `<language>` 允许值:`python`、`cpp`、`rust`、`go`、`multi`。若涉及多个语言,使用 `python+cpp`、`python+rust+go` 等形式,优先按语义顺序书写:`python+cpp` > `python+cpp+rust+go`。
202
+ - 若是一处跨语言同步改动,正文必须补充:
203
+ 1. 变更概述;
204
+ 2. 涉及语言与文件范围;
205
+ 3. 语义一致性说明;
206
+ 4. 验证方式/测试命令。
207
+ - 主题中禁止仅写“update / optimize / fix”这类空泛描述,必须指明对象和语言,例如:
208
+ - `feat[python]:为 runtime ringbuffer 增加原生 Python 语义实现`
209
+ - `fix[cpp+rust]:修正 vyukov 退避策略与 arm64 调度兼容性`
210
+ - `test[python]:补充 ringbuffer 回归测试覆盖 close 与 wait_for_close`
211
+ - `docs[multi]:同步更新 ringbuffer 契约与跨语言语义说明`
212
+ - 若某次提交仅修改单一语言,主题中必须明确写出该语言;若跨语言同步提交,则必须写 `multi` 或多个语言组合;不得出现“无语言标记”的提交信息。
213
+ - 主题和正文都应优先使用中文,必要时保留英文术语(如 `RingBuffer`、`QueueFullError`、`try_push`)作为对象标识。
214
+ - 提交信息必须保持可审计、可分组、可检索,方便后续基于语言维度筛选 commit。
215
+
216
+ 示例:
217
+
218
+ ```text
219
+ feat[python]:为 runtime ringbuffer 增加原生 Python 语义实现
220
+
221
+ - 新增 quant1x/runtime/ringbuffer.py,保留 try_push / try_pop / push / pop / close / wait_for_close 语义
222
+ - 目标为与 Go/C++/Rust 的 spec 契约保持一致,避免 Python 侧语义漂移
223
+ - 验证:PYTHONPATH=. python -m unittest quant1x.runtime.ringbuffer_test
224
+ ```
225
+
226
+ ```text
227
+ fix[cpp+rust]:修正 vyukov 退避策略,消除 arm64 争抢下的 convoy 效应
228
+
229
+ - 调整 backoff 退避策略,统一 C++ 与 Rust 的调度行为
230
+ - 重点修复 aarch64 上 yield/isb 差异导致的性能退化
231
+ - 说明:该修复仅影响调度策略,不改变 ringbuffer 语义契约
232
+ - 验证:cargo bench --bench vyukov_bench
233
+ ```
234
+
235
+ ```text
236
+ test[python+go]:补充 ringbuffer 语义回归测试,覆盖 close 与阻塞等待行为
237
+
238
+ - 以 Python 作为 spec 锚点,Go 侧对齐测试语义
239
+ - 验证:python -m unittest quant1x.runtime.ringbuffer_test
240
+ ```
241
+
242
+ ### 提交前检查清单(Checklist)
243
+
244
+ 在执行 `git commit` 之前,AI 必须逐项核对:
245
+
246
+ - [ ] 主题是否符合 `type[language]:summary` 模板?
247
+ - [ ] `type` 是否真实反映本次变更类型(feat / fix / refactor / test / perf / docs / chore)?
248
+ - [ ] `language` 是否准确标明本次涉及的开发语言,未标注或误标注均视为不合规?
249
+ - [ ] 若涉及多语言,是否使用 `python+cpp`、`python+rust+go` 等组合形式,而非笼统写 `multi`?
250
+ - [ ] 标题是否避免“update / optimize / fix”这类空泛描述,是否明确对象和影响?
251
+ - [ ] 正文是否包含:变更概述、涉及语言与文件范围、语义一致性说明、验证方式/命令?
252
+ - [ ] 若为跨语言同步改动,是否说明了语义一致性与测试验证方式?
253
+ - [ ] 是否未包含版本号、Git Tag、发布相关字符串?
254
+ - [ ] 是否使用中文为主,必要时保留英文术语作为对象标识?
255
+ - [ ] 是否能在审计时根据语言维度快速过滤和回溯?
256
+
257
+ 提交未满足以上任一项,必须在提交前修正,不能直接提交。
258
+
191
259
  ## 十、一句话总结(给 AI 的记忆锚点)
192
260
 
193
261
  > Quant1X 是多语言语义同构系统,Python 是 Spec,C++ 是 Truth,Rust / Go 是对齐实现,I/O 边界死守 `snake_case`。