scientific-computing-system 2.2.7__tar.gz → 2.2.8__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 (427) hide show
  1. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/CHANGELOG.md +1795 -1775
  2. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/CITATION.cff +54 -54
  3. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/PKG-INFO +1 -1
  4. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/codemeta.json +28 -28
  5. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/hypothesis_demo.py +0 -0
  6. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/package.json +45 -45
  7. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/pyproject.toml +327 -327
  8. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/_version.py +9 -9
  9. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/validation/checks.py +22 -12
  10. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_property_invariants.py +15 -13
  11. scientific_computing_system-2.2.8/tests/test_validation_bounds_nonfinite_regression.py +27 -0
  12. scientific_computing_system-2.2.8/tests/test_validation_nonfinite_thresholds_regression.py +57 -0
  13. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/benchmarks.yml +0 -0
  14. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/bot-reviewer.yml +0 -0
  15. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/changelog.yml +0 -0
  16. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/cli-package-smoke.yml +0 -0
  17. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/codeql.yml +0 -0
  18. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/npm-publish.yml +0 -0
  19. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/pr-automation.yml +0 -0
  20. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/pypi-registry-smoke.yml +0 -0
  21. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/release.yml +0 -0
  22. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.github/workflows/tests.yml +0 -0
  23. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/.gitignore +0 -0
  24. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/CONTRIBUTING.md +0 -0
  25. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/LICENSE +0 -0
  26. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/README.md +0 -0
  27. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/SECURITY.md +0 -0
  28. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/benchmarks/results.json +0 -0
  29. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/benchmarks/robust_runner.py +0 -0
  30. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/benchmarks/run_benchmarks.py +0 -0
  31. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/bin/scs.js +0 -0
  32. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/dashboard/app.py +0 -0
  33. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/ARCHITECTURE.md +0 -0
  34. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/CASE_STUDY_HUBBLE.md +0 -0
  35. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/CASE_STUDY_QUANTUM_ML.md +0 -0
  36. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/api.md +0 -0
  37. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/assets/icon.svg +0 -0
  38. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/assets/logo.svg +0 -0
  39. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/benchmarks.md +0 -0
  40. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/checks/verify_provenance_claims.py +0 -0
  41. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/cookbook.md +0 -0
  42. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/getting-started.md +0 -0
  43. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/index.md +0 -0
  44. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/maintenance.md +0 -0
  45. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/ml_reference.md +0 -0
  46. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/related.md +0 -0
  47. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/research-workflows.md +0 -0
  48. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/stylesheets/extra.css +0 -0
  49. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tour_of_numerical_methods.md +0 -0
  50. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/core_demo.md +0 -0
  51. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/data_analysis_demo.md +0 -0
  52. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/diffeq_demo.md +0 -0
  53. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/fft2_demo.md +0 -0
  54. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/graph_demo.md +0 -0
  55. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/hypothesis_demo.md +0 -0
  56. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/hypothesis_tests_demo.md +0 -0
  57. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/hypothesis_with_stats_demo.md +0 -0
  58. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/knowledge_demo.md +0 -0
  59. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/linalg_demo.md +0 -0
  60. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/math_utils_demo.md +0 -0
  61. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/ml_advanced_demo.md +0 -0
  62. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/ml_and_viz_demo.md +0 -0
  63. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/ml_demo.md +0 -0
  64. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/modeling_demo.md +0 -0
  65. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/montecarlo_demo.md +0 -0
  66. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/nlp_attention_demo.md +0 -0
  67. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/nlp_bpe_demo.md +0 -0
  68. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/nlp_mini_gpt_demo.md +0 -0
  69. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/nlp_viz.md +0 -0
  70. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/numerical_integration_demo.md +0 -0
  71. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/optimization_demo.md +0 -0
  72. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/pandas_io_demo.md +0 -0
  73. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/pca_demo.md +0 -0
  74. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/probability_demo.md +0 -0
  75. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/quantum_demo.md +0 -0
  76. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/quick_start.md +0 -0
  77. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/scientific_demo.md +0 -0
  78. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/signals_demo.md +0 -0
  79. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/stats_demo.md +0 -0
  80. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/stiff_ode_demo.md +0 -0
  81. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/tutorials/time_series_demo.md +0 -0
  82. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/docs/why-pure-python.md +0 -0
  83. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/core_demo.py +0 -0
  84. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/data_analysis_demo.py +0 -0
  85. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/diffeq_demo.py +0 -0
  86. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/discovery_pipeline_demo.py +0 -0
  87. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/ensemble_showcase.py +0 -0
  88. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/fft2_demo.py +0 -0
  89. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/graph_demo.py +0 -0
  90. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/hypothesis_custom_generator.py +0 -0
  91. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/hypothesis_tests_demo.py +0 -0
  92. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/hypothesis_with_stats_demo.py +0 -0
  93. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/interpolate_demo.py +0 -0
  94. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/knowledge_demo.py +0 -0
  95. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/linalg_demo.py +0 -0
  96. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/math_utils_demo.py +0 -0
  97. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/ml_and_viz_demo.py +0 -0
  98. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/modeling_demo.py +0 -0
  99. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/montecarlo_demo.py +0 -0
  100. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/nlp_attention_demo.py +0 -0
  101. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/nlp_bpe_demo.py +0 -0
  102. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/nlp_mini_gpt_demo.py +0 -0
  103. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/nlp_viz_demo.py +0 -0
  104. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/numerical_integration_demo.py +0 -0
  105. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/optimization_demo.py +0 -0
  106. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/pca_demo.py +0 -0
  107. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/pde_demo.py +0 -0
  108. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/plot_demo.py +0 -0
  109. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/plotting_notebook.ipynb +0 -0
  110. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/probability_demo.py +0 -0
  111. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/quantum_demo.py +0 -0
  112. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/scientific_demo.py +0 -0
  113. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/signals_demo.py +0 -0
  114. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/stats_demo.py +0 -0
  115. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/examples/tour_of_numerical_methods.ipynb +0 -0
  116. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/index.js +0 -0
  117. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/mkdocs.yml +0 -0
  118. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/npm.test.js +0 -0
  119. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/paper.bib +0 -0
  120. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/paper.md +0 -0
  121. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/requirements-build.lock +0 -0
  122. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/requirements-dev.lock +0 -0
  123. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/requirements.lock +0 -0
  124. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/check_release_toolchain.py +0 -0
  125. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/check_version_discipline.py +0 -0
  126. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/check_version_lockstep.py +0 -0
  127. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/publish.py +0 -0
  128. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/verify_cli_install.py +0 -0
  129. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/verify_cookbook.py +0 -0
  130. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/verify_ml_reference.py +0 -0
  131. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/verify_pypi_release.py +0 -0
  132. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/scripts/verify_release_integrity.py +0 -0
  133. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/__init__.py +0 -0
  134. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/__main__.py +0 -0
  135. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/_paths.py +0 -0
  136. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/bayes/__init__.py +0 -0
  137. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/bayes/conjugate.py +0 -0
  138. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/causal.py +0 -0
  139. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/__init__.py +0 -0
  140. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/__main__.py +0 -0
  141. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/_exit_codes.py +0 -0
  142. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/_handlers.py +0 -0
  143. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/_parser.py +0 -0
  144. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/_style.py +0 -0
  145. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/cli/_system_info.py +0 -0
  146. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/core/__init__.py +0 -0
  147. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/core/_numeric.py +0 -0
  148. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/core/models.py +0 -0
  149. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/__init__.py +0 -0
  150. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/dataset.py +0 -0
  151. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/loader.py +0 -0
  152. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/pandas_io.py +0 -0
  153. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/transform.py +0 -0
  154. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_analysis/viz.py +0 -0
  155. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_io/__init__.py +0 -0
  156. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_io/scientific.py +0 -0
  157. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/data_io/streaming.py +0 -0
  158. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/diffeq/__init__.py +0 -0
  159. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/diffeq/_implicit.py +0 -0
  160. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/diffeq/solvers.py +0 -0
  161. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/diffeq/symplectic.py +0 -0
  162. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/fractals/__init__.py +0 -0
  163. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/fractals/sets.py +0 -0
  164. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/genetics/__init__.py +0 -0
  165. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/genetics/sequence.py +0 -0
  166. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/graph/__init__.py +0 -0
  167. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/graph/algorithms.py +0 -0
  168. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/hypothesis/__init__.py +0 -0
  169. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/hypothesis/evaluator.py +0 -0
  170. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/hypothesis/generator.py +0 -0
  171. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/hypothesis/mining.py +0 -0
  172. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/infotheory/__init__.py +0 -0
  173. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/infotheory/measures.py +0 -0
  174. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/interpolate/__init__.py +0 -0
  175. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/knowledge/__init__.py +0 -0
  176. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/knowledge/graph.py +0 -0
  177. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/knowledge/notes.py +0 -0
  178. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/knowledge/retrieval.py +0 -0
  179. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/math_utils/__init__.py +0 -0
  180. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/math_utils/calculus.py +0 -0
  181. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/math_utils/linalg.py +0 -0
  182. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/math_utils/special.py +0 -0
  183. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/math_utils/svd.py +0 -0
  184. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/__init__.py +0 -0
  185. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/boosting.py +0 -0
  186. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/clustering.py +0 -0
  187. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/decomposition.py +0 -0
  188. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/ensemble.py +0 -0
  189. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/linear_models.py +0 -0
  190. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/metrics.py +0 -0
  191. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/model_selection.py +0 -0
  192. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/naive_bayes.py +0 -0
  193. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/neighbors.py +0 -0
  194. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/neural.py +0 -0
  195. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/preprocessing.py +0 -0
  196. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/tree.py +0 -0
  197. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/ml/voting.py +0 -0
  198. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/__init__.py +0 -0
  199. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/_base.py +0 -0
  200. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/_nodes.py +0 -0
  201. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/expression.py +0 -0
  202. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/fitting.py +0 -0
  203. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/model.py +0 -0
  204. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/modeling/solver.py +0 -0
  205. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/montecarlo/__init__.py +0 -0
  206. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/montecarlo/markov.py +0 -0
  207. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/montecarlo/methods.py +0 -0
  208. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/__init__.py +0 -0
  209. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/attention.py +0 -0
  210. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/autograd/__init__.py +0 -0
  211. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/autograd/_grad.py +0 -0
  212. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/autograd/ops.py +0 -0
  213. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/autograd/tensor.py +0 -0
  214. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/bpe.py +0 -0
  215. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/data.py +0 -0
  216. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/embed.py +0 -0
  217. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/layers.py +0 -0
  218. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/model.py +0 -0
  219. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/optim.py +0 -0
  220. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/training.py +0 -0
  221. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/nlp/viz.py +0 -0
  222. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/numerical_integration/__init__.py +0 -0
  223. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/numerical_integration/quadrature.py +0 -0
  224. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/optimization/__init__.py +0 -0
  225. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/optimization/_metaheuristics.py +0 -0
  226. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/optimization/constrained.py +0 -0
  227. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/optimization/minimize.py +0 -0
  228. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/pde/__init__.py +0 -0
  229. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/plot/__init__.py +0 -0
  230. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/plot/_backend.py +0 -0
  231. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/plot/charts.py +0 -0
  232. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/probability/__init__.py +0 -0
  233. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/probability/_advanced.py +0 -0
  234. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/probability/distributions.py +0 -0
  235. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/probability/extra_distributions.py +0 -0
  236. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/provenance/__init__.py +0 -0
  237. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/provenance/manifest.py +0 -0
  238. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/py.typed +0 -0
  239. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/quantum/__init__.py +0 -0
  240. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/quantum/circuit.py +0 -0
  241. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/quantum/multi_qubit.py +0 -0
  242. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/quantum/simulator.py +0 -0
  243. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/scientific/__init__.py +0 -0
  244. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/scientific/constants.py +0 -0
  245. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/scientific/formulas.py +0 -0
  246. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/sensitivity.py +0 -0
  247. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/signals/__init__.py +0 -0
  248. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/signals/filters.py +0 -0
  249. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/signals/processing.py +0 -0
  250. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/signals/stft.py +0 -0
  251. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/signals/wavelet.py +0 -0
  252. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/__init__.py +0 -0
  253. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/_distributions.py +0 -0
  254. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/bootstrap.py +0 -0
  255. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/descriptive.py +0 -0
  256. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/hypothesis_tests.py +0 -0
  257. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/multiple_testing.py +0 -0
  258. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/nonparametric.py +0 -0
  259. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/power.py +0 -0
  260. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/regression.py +0 -0
  261. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/stats/time_series.py +0 -0
  262. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/tools/__init__.py +0 -0
  263. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/tools/adapters.py +0 -0
  264. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/tools/registry.py +0 -0
  265. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/uncertainty/__init__.py +0 -0
  266. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/uncertainty/propagation.py +0 -0
  267. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/units/__init__.py +0 -0
  268. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/units/core.py +0 -0
  269. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/validation/__init__.py +0 -0
  270. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/validation/adequacy.py +0 -0
  271. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/validation/drift.py +0 -0
  272. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/validation/report.py +0 -0
  273. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/wavelets/__init__.py +0 -0
  274. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/wavelets/haar.py +0 -0
  275. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/__init__.py +0 -0
  276. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/engine.py +0 -0
  277. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/gates.py +0 -0
  278. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/orchestrator.py +0 -0
  279. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/selection.py +0 -0
  280. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/tooling.py +0 -0
  281. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/src/cds/workflow/types.py +0 -0
  282. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/__init__.py +0 -0
  283. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/conftest.py +0 -0
  284. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_advanced_fitting.py +0 -0
  285. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_completion_coverage.py +0 -0
  286. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_guard_coverage.py +0 -0
  287. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening.py +0 -0
  288. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_c1.py +0 -0
  289. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_c2.py +0 -0
  290. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_c3.py +0 -0
  291. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_c4.py +0 -0
  292. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_coverage.py +0 -0
  293. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_audit_hardening_h1.py +0 -0
  294. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_bayes_v2.py +0 -0
  295. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_benchmarks.py +0 -0
  296. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_bootstrap.py +0 -0
  297. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_causal.py +0 -0
  298. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_cli.py +0 -0
  299. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_cli_color.py +0 -0
  300. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_cli_exit_codes.py +0 -0
  301. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_cli_extended.py +0 -0
  302. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_cli_system_info.py +0 -0
  303. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_codemeta_version_lockstep.py +0 -0
  304. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_constrained_opt.py +0 -0
  305. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_core.py +0 -0
  306. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_analysis.py +0 -0
  307. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_analysis_lazy_bridge.py +0 -0
  308. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_analysis_pandas_io.py +0 -0
  309. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_io.py +0 -0
  310. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_io_optional_backends.py +0 -0
  311. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_data_io_scientific.py +0 -0
  312. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_dataset.py +0 -0
  313. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_dev_numpy_pin_contract.py +0 -0
  314. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_diffeq.py +0 -0
  315. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_diffeq_implicit.py +0 -0
  316. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_domain_validation.py +0 -0
  317. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_edge_misc_numerical.py +0 -0
  318. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_edge_ml_quantum_linalg.py +0 -0
  319. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_edge_nlp.py +0 -0
  320. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_edge_quantum_evaluator_cli.py +0 -0
  321. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_edge_stats_optimization_signals.py +0 -0
  322. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_extra_distributions.py +0 -0
  323. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_fft2.py +0 -0
  324. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_fitting_bootstrap.py +0 -0
  325. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_fractals.py +0 -0
  326. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_genetics.py +0 -0
  327. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_graph.py +0 -0
  328. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_hardening_privacy_provenance.py +0 -0
  329. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_hypothesis.py +0 -0
  330. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_hypothesis_engine.py +0 -0
  331. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_hypothesis_mining.py +0 -0
  332. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_hypothesis_tests.py +0 -0
  333. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_infotheory.py +0 -0
  334. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_interpolate.py +0 -0
  335. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_knowledge.py +0 -0
  336. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_layering.py +0 -0
  337. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_linalg_extended.py +0 -0
  338. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_linalg_qr_cholesky.py +0 -0
  339. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_markov.py +0 -0
  340. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_math_utils.py +0 -0
  341. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_boosting.py +0 -0
  342. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_clustering.py +0 -0
  343. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_ensemble.py +0 -0
  344. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_knn.py +0 -0
  345. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_linreg.py +0 -0
  346. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_logreg.py +0 -0
  347. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_metrics.py +0 -0
  348. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_model_selection.py +0 -0
  349. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_naive_bayes.py +0 -0
  350. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_pca.py +0 -0
  351. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_preprocessing.py +0 -0
  352. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_tree.py +0 -0
  353. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_viz.py +0 -0
  354. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_ml_voting.py +0 -0
  355. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_modeling.py +0 -0
  356. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_modeling_fit_validation.py +0 -0
  357. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_montecarlo.py +0 -0
  358. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_multi_qubit.py +0 -0
  359. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_attention.py +0 -0
  360. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_autograd.py +0 -0
  361. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_bpe.py +0 -0
  362. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_embed.py +0 -0
  363. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_layers.py +0 -0
  364. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_model.py +0 -0
  365. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_training.py +0 -0
  366. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_nlp_viz.py +0 -0
  367. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_numerical_integration.py +0 -0
  368. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_numerical_invariants.py +0 -0
  369. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_numerical_oracles.py +0 -0
  370. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_optimization.py +0 -0
  371. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_optimization_metaheuristics.py +0 -0
  372. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_path_confinement.py +0 -0
  373. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_pde.py +0 -0
  374. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_plot_charts.py +0 -0
  375. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_plot_lazy.py +0 -0
  376. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_power.py +0 -0
  377. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_probability.py +0 -0
  378. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_probability_advanced.py +0 -0
  379. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_protocol_placeholders.py +0 -0
  380. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_provenance.py +0 -0
  381. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_provenance_audit_hardening.py +0 -0
  382. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_provenance_claims.py +0 -0
  383. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_public_api.py +0 -0
  384. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_quantum.py +0 -0
  385. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_readme_badges.py +0 -0
  386. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_readme_surface.py +0 -0
  387. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_release_contract.py +0 -0
  388. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_release_toolchain.py +0 -0
  389. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_retrieval.py +0 -0
  390. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_runtime_dependency_graph.py +0 -0
  391. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_scientific.py +0 -0
  392. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_seed_hygiene.py +0 -0
  393. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_selection_audit_hardening.py +0 -0
  394. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_sensitivity.py +0 -0
  395. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_sensitivity_global.py +0 -0
  396. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_signals.py +0 -0
  397. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_signals_filters.py +0 -0
  398. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_special_invariants.py +0 -0
  399. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_special_numerics.py +0 -0
  400. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_statistical_audit.py +0 -0
  401. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stats.py +0 -0
  402. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stats_audit_coverage.py +0 -0
  403. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stats_multiple_testing.py +0 -0
  404. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stats_nonparametric.py +0 -0
  405. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stats_time_series.py +0 -0
  406. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_stft.py +0 -0
  407. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_streaming_analytics.py +0 -0
  408. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_svd.py +0 -0
  409. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_symplectic.py +0 -0
  410. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_tool_adapters.py +0 -0
  411. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_tools_registry.py +0 -0
  412. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_uncertainty.py +0 -0
  413. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_units.py +0 -0
  414. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_validation.py +0 -0
  415. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_validation_adequacy.py +0 -0
  416. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_validation_advanced.py +0 -0
  417. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_validation_drift.py +0 -0
  418. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_verify_release_integrity.py +0 -0
  419. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_wavelet.py +0 -0
  420. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_wavelets_v2.py +0 -0
  421. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow.py +0 -0
  422. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_gates.py +0 -0
  423. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_orchestrator.py +0 -0
  424. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_orchestrator_blocked_review.py +0 -0
  425. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_selection.py +0 -0
  426. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_selection_coverage.py +0 -0
  427. {scientific_computing_system-2.2.7 → scientific_computing_system-2.2.8}/tests/test_workflow_tooling.py +0 -0
@@ -1,1775 +1,1795 @@
1
- # Changelog
2
-
3
- All notable changes to **scientific-computing-system** will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [v2.2.6] - 2026-10-13
9
-
10
- ### Housekeeping — second-round neighbour sweep
11
-
12
- - `transpose` shares the ragged-input contract the rest of the matrix API has
13
- held since 2.2.5. It indexed only the leading row's width, so a short row
14
- lost entries silently (`[[1.0],[2.0,3.0]]` became `[[1.0, 2.0]]`): the
15
- result described a matrix nobody supplied. It now fails closed through the
16
- same `_require_rectangular` check `mat_mul` and Cholesky use.
17
- - Geometric PMF boundary pinned: `geometric_pmf(0, p)` is 0 (no trial counted
18
- 1-based), and extreme `(k, p)` stays finite.
19
- - `poisson_pmf(0, 0)` is 1 and the log-space PMFs were probed at their
20
- previously-crashing inputs; no remaining overflow class found in the
21
- probability module.
22
-
23
- ## [v2.2.5] - 2026-10-12
24
-
25
- ### Housekeeping — audit hardening
26
-
27
- - Closes the findings of the full-repository audit: patched the concrete
28
- defects (correctness, fail-closed behaviour, platform independence),
29
- wired every standalone guard into CI, removed dead or duplicated code
30
- paths, and pinned every doc claim to a test so it cannot silently
31
- drift again. Regression tests fail without the corresponding fix.
32
-
33
- ## [Unreleased]
34
-
35
- ### Distribution status of 2.2.2 — read this before assuming npm has it
36
-
37
- The two registries are **not** in the same state for 2.2.2.
38
-
39
- | Registry | `2.2.2` | Build attestation |
40
- |---|---|---|
41
- | **PyPI** `scientific-computing-system` | **published** | **PEP 740 provenance present** |
42
- | **npm** `scientific-computing-system` | **NOT published** | none — the version does not exist on npm |
43
-
44
- PyPI 2.2.2 is live and carries a PEP 740 attestation. Verified against the live
45
- registries on 2026-10-05: the PEP 740 per-file provenance endpoint returns
46
- **HTTP 200** for both files.
47
-
48
- ```
49
- curl -sS -o /dev/null -w '%{http_code}\n' \
50
- https://pypi.org/integrity/scientific-computing-system/2.2.2/scientific_computing_system-2.2.2-py3-none-any.whl/provenance # 200
51
- curl -sS -o /dev/null -w '%{http_code}\n' \
52
- https://pypi.org/integrity/scientific-computing-system/2.2.2/scientific_computing_system-2.2.2.tar.gz/provenance # 200
53
- ```
54
-
55
- npm 2.2.2 does not exist. The published npm versions remain `1.0.0`, `2.2.0` and
56
- `2.2.1`. Nothing about the npm launcher is broken — the publish is blocked on a
57
- one-time npmjs.com registration, described next.
58
-
59
- ### Pending: register the npm trusted publisher (one-time, maintainer, in a browser)
60
-
61
- npmjs.com has **no trusted publisher** configured for the package
62
- `scientific-computing-system`. Until one exists, the OIDC path cannot complete a
63
- publish, and npm publishes no provenance for this package.
64
-
65
- The coordinates to enter on npmjs.com → package `scientific-computing-system` →
66
- **Settings → Trusted Publisher → GitHub Actions**:
67
-
68
- | Field | Value |
69
- |---|---|
70
- | Organization or user | `Furox-Art` |
71
- | Package | `scientific-computing-system` |
72
- | Workflow filename | `npm-publish.yml` |
73
- | Environment name | `npm` |
74
- | Allowed actions | **`npm publish`** — must be enabled, see the warning below |
75
-
76
- **The allowed-actions field is not optional in practice.** npm's current UI grants
77
- `npm stage publish` by default on newly created configurations and makes direct
78
- `npm publish` **opt-in**. This repository's workflow calls `npm publish` directly,
79
- so registering the publisher *without* also allowing `npm publish` will leave the
80
- publish failing — with a permission error this time rather than a 404.
81
-
82
- The same registration from the CLI, using the maintainer's own npm login and 2FA:
83
-
84
- ```
85
- npm trust github --file npm-publish.yml \
86
- --repo Furox-Art/scientific-computing-system --env npm --allow-publish
87
- ```
88
-
89
- ### The publish mode default is unchanged, and was never set to token
90
-
91
- The mode is the `workflow_dispatch` input `use_token_fallback`, whose default is
92
- `false` — that is **OIDC**. There is no `npm_publish_mode` variable; the repository
93
- has **no Actions variables at all** (none at repository or organization scope), and
94
- `npm_publish_mode` appears nowhere in the tree. Nothing needs to be switched back:
95
- OIDC is already the default, and token mode remains an explicit per-run opt-in.
96
-
97
- `NPM_TOKEN` does still exist as a repository secret. It is what token mode would
98
- use, and it should be deleted once the trusted publisher is registered and the
99
- first OIDC publish has succeeded.
100
-
101
- ### Fixed: a 404 from npm no longer reads as "already published"
102
-
103
- `npm publish` answered
104
-
105
- ```
106
- npm error 404 The requested resource 'scientific-computing-system@2.2.2' could not
107
- be found or you do not have permission to access it.
108
- ```
109
-
110
- on runs 37268729425 and 37269325567, and that single line cannot distinguish the
111
- two real causes. npm deliberately does not tell an unauthenticated caller whether a
112
- package exists, so **an unregistered trusted publisher is reported as 404, not as
113
- 401 or 403.**
114
-
115
- Two failure surfaces were making that expensive to diagnose, and both now say so
116
- out loud. Neither changes what the workflow does; both only change what it prints.
117
-
118
- - **The publish step** now names the real cause when npm returns 404, states that
119
- the package exists and the version is absent, prints the npmjs.com fields above,
120
- and calls out the `npm publish` allowed-action requirement. A rejected or absent
121
- token looks different (401, or `ENEEDAUTH`), and the step says that too.
122
- - **The version-existence gate** now warns, at the point where it would otherwise
123
- tell someone to bump the version, that a 404 also means "unauthorized". Bumping
124
- to escape a 404 consumes a release number on both registries and still will not
125
- publish while the publisher is unregistered.
126
-
127
- Worth recording precisely: in **both** runs the version gate **passed**. The
128
- tarball built, provenance was signed and submitted to the Sigstore transparency
129
- log, and only the `PUT` failed. So both runs did prove the authentication failure,
130
- and the fix is the registration above — not a version bump.
131
-
132
- ## [v2.2.4] - 2026-10-12
133
-
134
- ### Housekeeping — release alignment
135
-
136
- - Publishes the post-2.2.3 repository state (single-shot automatic npm
137
- publishing, #165) to PyPI and npm: the 2.2.3 upload predates that commit, so
138
- both registries were one commit behind `main`. No behavioural change.
139
-
140
- ## [v2.2.3] - 2026-10-05
141
-
142
- This release exists to exercise the OIDC trusted-publish path, now that the
143
- npmjs.com trusted publisher for `scientific-computing-system` is registered.
144
-
145
- The previous npm 2.2.2 was published in token mode and therefore carries no
146
- attestation. Nothing about the launcher changed: `src/` is untouched since
147
- 2.2.2, and the only source change in this release is the version string itself.
148
-
149
- ## [v2.2.2] - 2026-10-05
150
-
151
- Clears the last 17 open CodeQL alerts in this repository. None of them was a
152
- security vulnerability, and **none was a logic defect** — no discarded result, no
153
- missing `return`. Nothing is suppressed: there is no `# nosec`, no path exclusion
154
- and no `codeql.config` entry.
155
-
156
- ### Behaviour change
157
-
158
- **One, and it is a removal:** the private path `cds.cli._parser._build_parser` no
159
- longer resolves.
160
-
161
- `_build_parser` was an alias for `build_parser`, kept for backwards
162
- compatibility. It was defined in `cds.cli._parser` but imported and re-exported by
163
- `cds.cli.__init__`, so within its own module it was genuinely unreferenced —
164
- which is exactly what `py/unused-global-variable` reported. The assignment has
165
- moved to `cds.cli.__init__`, beside its only consumer and inside the `__all__`
166
- that already exports it.
167
-
168
- - `cds.cli._build_parser` is unchanged: still present, still in `__all__`, still
169
- the same object as `cds.cli.build_parser`. This is the documented
170
- backwards-compatibility surface and it keeps working.
171
- - `cds.cli._parser._build_parser` is gone. Nothing in this repository referenced
172
- it and the name is underscore-private, but a downstream script that reached
173
- into the private submodule would break.
174
-
175
- There is now a test pinning the alias, because the original defect was that
176
- nothing asserted it existed.
177
-
178
- ### Fixed
179
-
180
- - **Protocol placeholders are docstrings, not bare `...`.** Nine
181
- `py/ineffectual-statement` alerts across `src/cds/ml/model_selection.py`,
182
- `src/cds/ml/voting.py` and `src/cds/tools/adapters.py` were the conventional
183
- `...` terminating a `typing.Protocol` method. These are false positives in the
184
- strict sense: `...` is the documented placeholder for a structurally-typed
185
- method whose implementation lives in the real backend module, and no code path
186
- executes it. `SoftVotingModel` is the only `@runtime_checkable` one, and
187
- `isinstance` against a runtime protocol inspects attribute *presence* without
188
- calling the body.
189
-
190
- They became docstrings rather than `pass` because coverage.py excludes an
191
- ellipsis-only body but counts `pass`; measured, swapping it in drops those
192
- lines from 100% to 75% and breaks the coverage gate. `raise NotImplementedError`
193
- has the same coverage problem and would additionally change behaviour if the
194
- body were ever reached. `src/cds` already contained nine docstring-only bodies
195
- with no alert on any of them.
196
-
197
- - **`src/cds/tools/registry.py` imports `importlib` one way.** Three spellings
198
- were mixed: `import importlib`, `import importlib.util` and
199
- `from importlib import metadata`. The first was fully subsumed by the second.
200
- Now `import importlib.metadata` and `import importlib.util`, with call sites
201
- fully qualified. Four monkeypatch targets in `tests/` were retargeted to match.
202
-
203
- - **Four `py/unnecessary-lambda` alerts in the test suite.** `lambda x: max(x)`
204
- and `lambda values: sum(values)` are plain wrappers around a callable; the
205
- callables are now passed directly.
206
-
207
- - **`tests/test_fitting_bootstrap.py` imports `cds.modeling.fitting` one way.**
208
- A module-level `from ... import` coexisted with function-local
209
- `import ... as fitting`. The single `import ... as fitting` form is used now and
210
- the module-level names are qualified through it.
211
-
212
- ### Added
213
-
214
- - **`tests/test_protocol_placeholders.py`** pins the protocol bodies on the AST,
215
- because a docstring-only body and a docstring followed by `pass` compile to
216
- almost identical instructions and only the syntax tree tells them apart. It also
217
- asserts the placeholder semantics (`None` when called unbound), that
218
- `SoftVotingModel` is still a working structural contract, and that every
219
- declared signature and annotation still resolves. Negative-controlled against
220
- four mutations, all caught: docstring-plus-`pass`, `...` reinstated, body
221
- replaced by a real statement, and a statement appended after the docstring.
222
-
223
- ### Changed
224
-
225
- - README's pasted `cds --version` transcript now reads `System version 2.2.2`.
226
- Every provenance and attestation statement in `README.md` and `SECURITY.md`
227
- still refers to **2.2.1** deliberately: those describe the published release,
228
- including its digests, and remain true until a newer one ships.
229
-
230
-
231
- ### Fixed
232
-
233
- - **Provenance claims are now scoped, measured, and guarded.** A follow-up report
234
- asserted that PyPI had no PEP 740 attestation either. Re-measured directly, that
235
- is **not** the case, so the previous text was left standing and made precise
236
- rather than weakened:
237
-
238
- - PyPI **2.2.1** serves a PEP 740 provenance bundle for **both** the wheel and
239
- the sdist (HTTP 200 on the per-file `/integrity/.../provenance` endpoint),
240
- and each bundle's `subject` digest equals the `sha256` PyPI publishes for
241
- that file. The 404 in the report came from requesting
242
- `https://pypi.org/integrity/scientific-computing-system/2.2.1/`, which is a
243
- directory, not the per-file endpoint.
244
- - npm **2.2.1** has **no** attestation: the attestations endpoint returns 404.
245
- This part of the report was correct.
246
-
247
- The security posture is therefore unchanged and more precisely stated. What
248
- changed: `SECURITY.md` now separates the three things that were being conflated
249
- — a **PEP 740 attestation** (Sigstore-signed, attests *who built this*),
250
- **npm `dist.signatures`** (registry transport signing, attests nothing about
251
- the build), and a **content digest** (`sha256` on PyPI, `dist.integrity` on
252
- npm; pins *which bytes*, not *where they came from*). It lists the published
253
- digests to pin, gives the commands that verify them, and states the exact
254
- trusted-publisher coordinates still to be registered for npm.
255
-
256
- - **Reproducible-build claim scoped to what was actually measured.** Two
257
- consecutive builds of the same commit with the same pinned backend produced
258
- byte-identical wheel and sdist. Those digests do **not** match the published
259
- ones (the release runs a hash-locked Linux toolchain; the check ran elsewhere),
260
- so the documentation now claims determinism for a fixed toolchain and
261
- explicitly declines to claim the published artifacts are bit-for-bit
262
- reproducible from source.
263
-
264
- - **npm launcher prerequisite re-verified.** With `cds` absent from `PATH`, the
265
- shim proceeds straight to interpreter resolution (`python`/`python3`/`py`) and
266
- runs `python -m cds`; it never looks for a `cds` console script. README,
267
- `SECURITY.md` and the docs already agreed on this wording, and it is now
268
- backed by an explicit check rather than by reading the source.
269
-
270
- ### Added
271
-
272
- - `docs/checks/verify_provenance_claims.py` — a guard that parses the attestation
273
- claims out of `README.md` and `SECURITY.md` and compares them against the live
274
- registries, failing if the prose asserts something the registries contradict.
275
- It also rejects prose that overstates `dist.integrity` as provenance or allows
276
- the attested subject to differ from the published digest. Negative-controlled:
277
- three false claims (PyPI not attested, npm attested, digest mismatch acceptable)
278
- each turn it red. Wiring it into CI is left to the workflow owner; this change
279
- is docs-only by scope.
280
-
281
- ## [v2.2.1] - 2026-10-04
282
-
283
- Documentation and release-surface corrections. **No library behaviour change**:
284
- nothing under `src/cds/` was modified except the `__version__` constant, so no
285
- numerical kernel, public API signature or CLI subcommand differs from 2.2.0.
286
-
287
- The reason this patch release exists: `README.md` is the `long_description`, and
288
- PyPI only re-reads it when a new release is uploaded. 2.2.0 shipped the README as
289
- it stood before the truthfulness work below, so the PyPI project page for 2.2.0
290
- still advertises claims the repository has since retracted. Publishing 2.2.1 is
291
- what makes the corrected README the one PyPI renders.
292
-
293
- ### Fixed
294
-
295
- - **README performance claim corrected to the committed artifact.** The "catch"
296
- paragraph asserted "~0.05 s versus ~0.0001 s ... roughly 580x slower" and
297
- described it as "this machine's benchmark run", while pointing readers at
298
- `docs/benchmarks.md` for "the hardware they came from". `benchmarks/results.json`
299
- actually records 0.0696 s versus 0.000060 s (**1154.8x**) at commit `7213425`,
300
- and that same file records Platform / CPU / Python / NumPy as "not recorded"
301
- with an explicit "treat the absolute timings as unverified" warning. The line
302
- added by the earlier truthfulness commit therefore contradicted the warnings it
303
- shipped alongside. Both the README and `docs/why-pure-python.md` now quote the
304
- artifact's own numbers and state that the environment was not recorded.
305
-
306
- - **npm launcher prerequisite stated correctly.** README and `SECURITY.md` said
307
- the `scs` shim works once `cds` is "on your PATH". `index.js` resolves an
308
- interpreter (`python`/`python3`/`py`) and runs `python -m cds`; it never looks
309
- for a console script on `PATH`. Corrected to "requires the Python distribution
310
- installed so that `python -m cds` resolves".
311
-
312
- - **Stale version references left behind by the 2.2.1 bump.** The README's pasted
313
- `cds --version` transcript still read `System version 2.2.0` after the version
314
- moved, and `SECURITY.md` still recommended pinning `==2.2.0`. Since the README
315
- is the `long_description`, that line would have shipped verbatim to the PyPI
316
- project page. Both were re-derived from live commands at 2.2.1.
317
-
318
- Every other pasted transcript was re-checked against the installed 2.2.1 wheel
319
- and found current: the quickstart output (SVD singular values, damped-oscillator
320
- final state, regression fit), `cds modules` printing 26 rows and omitting exactly
321
- the nine documented modules, the structural claims (34 subpackages, 35 public
322
- feature modules, 505 names / 342 functions / 163 classes), the benchmark ratio
323
- against `benchmarks/results.json`, and all five documented extras.
324
-
325
- Two further `SECURITY.md` claims were false and are corrected: `scs` was
326
- documented as needing a `cds` console script on `PATH` when the launcher
327
- resolves an interpreter and runs `python -m cds` (verified: the shim prints
328
- `System version 2.2.1` with no `cds` on `PATH`), and the PyPI attestation cell
329
- claimed a PEP 740 bundle for the published 2.2.0 when PyPI serves none.
330
-
331
- The pin example is now version-agnostic by construction, so it cannot rot at
332
- the next bump.
333
-
334
- - **Module-surface claims are now accurate.** "34 subpackages" silently omitted
335
- the two top-level public modules (`causal.py`, `sensitivity.py`), and
336
- "`cds modules` for the live list" was wrong twice over: that command prints a
337
- curated 26-entry subset and omits `bayes`, `causal`, `core`, `fractals`,
338
- `genetics`, `infotheory`, `interpolate`, `pde`, and `wavelets`. README,
339
- `docs/api.md` and `docs/index.md` now state the real counts and flag
340
- `cds modules` as a subset. The unsupported "46 public functions / 534 exports"
341
- hero claim does not exist in the repository or in any reachable commit; the
342
- README instead carries counts derived from the package itself (505 exports:
343
- 342 functions, 163 classes across 35 feature modules).
344
-
345
- - **Documentation no longer claims npm is unpublished.** npm 2.2.0 is live and
346
- npm is a supported channel, but `README.md` line 41 still said "npm is no
347
- longer published". Because `README.md` is listed in the npm `files` allowlist,
348
- that sentence shipped **verbatim inside the published 2.2.0 tarball**, so the
349
- npm package page contradicted its own README. `README.md`, `SECURITY.md` and
350
- `docs/related.md` now describe both channels accurately; the npm version badge
351
- is restored now that the registry and PyPI agree.
352
-
353
- - **A successful publish is no longer reported as a failure while npm is still
354
- propagating it.** `npm publish` returns as soon as the registry accepts the
355
- upload, but the version becomes readable on the read path asynchronously. The
356
- post-publish check read once, immediately, and on run `37136131220` got
357
- `npm error 404 No match found for version 2.2.0` — while 2.2.0 was in fact
358
- published and recorded by the registry ninety seconds later. A maintainer
359
- reading that run had every reason to believe the release had broken. Three
360
- sibling repositories hit the same false failure.
361
-
362
- The check now polls the registry with backoff over a budget of several minutes,
363
- succeeds on the first match, and still fails closed if the version genuinely
364
- never appears, emitting a `::warning::` first so a slow-but-successful publish
365
- is never read as a hard failure.
366
-
367
- It queries the registry's JSON API instead of `npm view`, which was a poor fit:
368
- it reports "absent" and "denied" with the same `E404`, and it resolves against
369
- the userconfig the job created for *writing*, so a read-only confirmation had no
370
- reason to touch publish credentials at all. Both directions are exercised
371
- against a stub registry, and the retry budget itself is asserted, since
372
- shortening it to make a test fast is what caused the bug.
373
-
374
- - **The publish path is now guarded rather than merely enabled.** The launcher
375
- contract test previously asserted that publishing stayed disabled, which would
376
- have silently passed against a disabled workflow. It now asserts a real
377
- `npm publish --provenance` invocation, `id-token: write`, the absence of
378
- `private: true`, the absence of the disabled stub, and the presence of every
379
- gate that makes a publish safe: the registry version-existence check, the
380
- `npm pack --dry-run` tarball allowlist, and the npm/Python version lockstep.
381
-
382
- - **The npm toolchain version floor rejected a compliant toolchain.** The first
383
- real publish run failed on this gate:
384
-
385
- ```
386
- npm --version | grep -Eq '^11\.(5[1-9]|[6-9][0-9])\.|^1[2-9]\.'
387
- ::error::npm 11.5.1+ is required for OIDC trusted publishing
388
- ```
389
-
390
- On Node 24, setup-node installs npm **11.19.0**. The `[6-9][0-9]` alternative
391
- covers minors 60-99, so `19` never matched and the gate failed on a toolchain
392
- that meets the floor. A regex cannot express "greater than or equal to" for a
393
- dotted version without enumerating every minor, which is exactly the mistake
394
- that shipped. The gate now parses the version, strips any leading `v` and
395
- prerelease suffix, and compares major/minor/patch as integers against 11.5.1.
396
- The Node half of the same gate ignored the patch component: it compared only
397
- major and minor, so `22.9.0` was accepted even though the documented floor is
398
- 22.14.0. Both halves now use the same integer comparison.
399
-
400
- - **Token-mode npm publish failed with `ENEEDAUTH` while holding a valid
401
- secret.** The run reached `npm publish` with `NODE_AUTH_TOKEN` populated and
402
- still got:
403
-
404
- ```
405
- npm error code ENEEDAUTH
406
- npm error need auth This command requires you to be logged in to
407
- https://registry.npmjs.org/
408
- ```
409
-
410
- Root cause: `actions/setup-node` was configured without `registry-url`, so it
411
- wrote no npm userconfig at all. `NODE_AUTH_TOKEN` on its own is inert — npm only
412
- substitutes it into a credential when some userconfig maps
413
- `//registry.npmjs.org/` to `${NODE_AUTH_TOKEN}`. With no such entry npm never
414
- attempts authentication, which is why the failure was `ENEEDAUTH` (no
415
- authentication attempted) rather than `E401` (attempted and rejected) even
416
- though the secret was present and correct. The fix is
417
- `registry-url: "https://registry.npmjs.org"` on `setup-node`.
418
-
419
- Separately, the credential check lived inline inside the publish step, so its
420
- failure text appeared in the log while `npm publish` was invoked anyway. It is
421
- now its own step ahead of both publish steps, so a non-zero exit ends the job
422
- before npm can run, and it covers the OIDC mode too (verifying the runner
423
- actually granted `id-token: write`, which the previous version never checked).
424
-
425
- - **The `bin` map is now pinned by tests, so a broken launcher command cannot
426
- ship silently.** The `npm warn publish "bin[scs]" script name bin/scs.js was
427
- invalid and removed` message had been reported as a defect that would leave
428
- the published package with no working `scs` command. **That report was wrong.**
429
- npm normalises the redundant `./` prefix and ships the entry either way; the
430
- packed tarball keeps `bin: { scs: "./bin/scs.js" }` alongside `bin/scs.js`, and
431
- installing it creates `scs`, `scs.cmd` and `scs.ps1` and `scs --version`
432
- succeeds. `axiomize@1.12.4`, published from the identical shape, ships the same
433
- and is not deprecated. No `package.json` change is required.
434
-
435
- What *is* a real hazard is the opposite: npm ships a `bin` pointing at a
436
- missing file, or one excluded by `files`, with **no warning at all**. Five
437
- tests now assert the bin map is a valid command-name to path mapping, that
438
- every target exists and is covered by `files`, that the shim carries a `node`
439
- shebang, and that the real tarball (`npm pack --dry-run --json`) still contains
440
- both the shim and the bin entry. One further test documents that the `./`
441
- prefix is intentional so the cosmetic warning is not "fixed" by a future
442
- maintainer.
443
-
444
- ### Added
445
-
446
- - **`tests/test_readme_surface.py`** derives the README's structural claims from
447
- `src/cds/` and from the installed package: subpackage count, presence of both
448
- top-level public modules, the export total, per-module table coverage, the
449
- benchmark ratio against `benchmarks/results.json`, and a guard against
450
- describing `cds modules` as exhaustive. This drift was previously invisible to
451
- CI, which is how it survived several releases. Verified by mutation: five
452
- separate re-introductions of the audited defects each turn the suite red.
453
-
454
- - **`codemeta.json` is now a locked version surface.** It was left out of the
455
- original five surfaces and drifted: it still declared `2.1.0` after the package
456
- reached 2.2.0, while every other surface had moved. CodeMeta is a
457
- machine-readable publication record, so a stale `version` there advertises the
458
- previous release to every automated consumer while the installed package
459
- reports a different one. `scripts/check_version_lockstep.py` now reads it and
460
- `tests/test_codemeta_version_lockstep.py` fails CI on drift. It is also added
461
- to the sdist allowlist, without which that suite failed with `FileNotFoundError`
462
- when run from an unpacked sdist.
463
-
464
- - README coverage: `cds.core` and `cds.graph` rows, `examples/` (35 runnable
465
- files) and `dashboard/app.py` entries, all 13 CLI subcommands, the `[pandas]`
466
- extra, `paper.md`/`paper.bib` (JOSS) and `codemeta.json`, and a Contributing
467
- section with the `pip install -e ".[dev]"` / `pytest` / `mkdocs serve` loop and
468
- the 100% blended-coverage gate. Duplicated prose was removed (the supply-chain
469
- section now defers to `SECURITY.md` instead of restating it, and the generic
470
- "Common use cases" filler is gone).
471
-
472
- - **Two supported npm publish modes**, selected by the `use_token_fallback`
473
- dispatch input (boolean, default `false`):
474
- - **OIDC trusted publishing** (preferred, default) — `id-token: write`,
475
- `npm publish --provenance`. No registry secret involved.
476
- - **Token mode** (`use_token_fallback=true`) — uses the repository's existing
477
- `NPM_TOKEN` secret via `NODE_AUTH_TOKEN`. This is the mode in use while the
478
- npmjs.com trusted-publisher registration is pending.
479
-
480
- The token mode deliberately omits `--provenance`. Provenance is an OIDC-only
481
- Sigstore attestation: a token cannot mint one, and npm rejects the
482
- combination. The token mode prints a NOTICE that the release carries no
483
- provenance rather than passing a flag that cannot work or implying an
484
- attestation exists. Both modes are fail-closed: a requested mode with no usable
485
- credential exits non-zero with an actionable message, and token mode never runs
486
- automatically, so a broken OIDC configuration cannot silently downgrade to the
487
- long-lived credential.
488
-
489
- ### Changed
490
-
491
- - **npm publishing is real again.** This reverses two earlier decisions, both
492
- deliberate at the time and recorded here so the history is not silently erased:
493
- the decision in `52717c5` to disable npm publishing (which replaced the publish
494
- step with `run: echo "npm publishing is disabled; PyPI is the install path" &&
495
- exit 0`), and `"private": true` in `package.json`, added by `#140` while
496
- publishing was disabled. `private: true` makes `npm publish` refuse to run at
497
- all, so the flag had to go before the workflow could work. The `files` allowlist
498
- is retained: it is what keeps the repository (tests, CI workflows, 10k+
499
- statements of Python, promo media) out of the published tarball. The npm
500
- channel is on OIDC trusted publishing (`id-token: write`,
501
- `npm publish --provenance`); no long-lived registry token is used on the
502
- primary path.
503
-
504
- - README shortened with **higher** coverage: the supply-chain section dropped from
505
- 209 lines to a 3-line summary plus a link, and "The catch" reduced to a short
506
- paragraph.
507
-
508
- - **This release carries a PyPI attestation; 2.2.0 does not.** PyPI's JSON API
509
- reports zero PEP 740 attestation bundles for 2.2.0, which went out in token
510
- mode — a token cannot mint a Sigstore attestation. 2.2.1 is published by
511
- `release.yml` through `pypa/gh-action-pypi-publish` with Trusted Publishing
512
- (OIDC), so it will carry one, as long as the `pypi` environment's trusted
513
- publisher is configured — a misconfiguration fails the publish loudly rather
514
- than degrading silently.
515
-
516
- ## [v2.2.0]
517
-
518
- Security hardening of the provenance path surface: provenance manifest paths
519
- are confined (`src/cds/_paths.py`), and the runtime dependency graph is guarded.
520
- No numerical kernel or public API signature changed. (Content owned by the
521
- security agent; this heading exists to satisfy the version-lockstep gate.)
522
-
523
- ## [v2.1.0] - 2026-09-30
524
-
525
- Release-hardening pass covering the CI, quality-gate and packaging surface. No
526
- numerical kernel, public API signature or `cds` CLI subcommand changed.
527
-
528
- New public modules that first shipped in this release line (noted here because
529
- the release notes below cover only the hardening pass): `cds.validation`
530
- (cross-method verification, distribution-shift reporting), `cds.causal`
531
- (assumption-gated estimators — no causal-structure inference from observational
532
- correlation), `cds.sensitivity` (local and variance-based global sensitivity,
533
- identifiability), `cds.units` (SI dimensional analysis), `cds.workflow`
534
- (approval-gated, fail-closed orchestration), `cds.provenance` (manifests,
535
- hashing, checkpoints), `cds.data_io` (streaming I/O, optional HDF5/NetCDF),
536
- `cds.tools` (lazy optional-backend adapters), and `cds.uncertainty` (analytic
537
- and correlated Monte-Carlo propagation).
538
-
539
- ### Fixed
540
-
541
- - **npm launcher (`index.js`, `bin/scs.js`)**: the published launcher could not be
542
- parsed by Node (`SyntaxError: Unexpected token ';'`), and had it parsed it
543
- spawned `python -m scs.cli`, a module that has never existed in any release
544
- (the import name is `cds`). Both defects shipped in `1.0.0` on npm and were
545
- invisible because `npm test` was a placeholder that exited 1 without running
546
- anything. The launcher is now syntactically valid, targets `python -m cds`,
547
- propagates the child's exit status, and reports one actionable message when no
548
- interpreter is found.
549
- - **npm package contents**: `package.json` shipped no `files` allowlist, so a
550
- publish would have uploaded the whole repository (tests, workflows, 10k+
551
- statements of Python, promo media). Publication is now restricted to an
552
- explicit allowlist.
553
- - **npm version drift**: `package.json` declared `1.0.0` while the Python
554
- distribution was at `2.1.0`. It now tracks the Python version and CI fails on
555
- any drift.
556
- - **Version-discipline bypass under rebase merges**
557
- (`scripts/check_version_discipline.py --base-ref HEAD^1`): `HEAD^1` resolves to
558
- the previous commit of the *same branch*, so in a multi-commit rebase merge only
559
- the final commit's diff was inspected. A PR could change `src/cds/` in one
560
- commit, follow with an unrelated commit, and pass the gate with no version bump
561
- at all. The gate now diffs against the PR merge-base.
562
- - **Release fail-closed behaviour**: the publish job could report success after a
563
- verification step had failed. That path is closed; every verification failure
564
- now fails the job before any registry or tag mutation.
565
- - **Docs deployment ordering**: `deploy-docs` depended only on the `test` matrix,
566
- so gh-pages could be updated from a run whose `audit`, `version_discipline` or
567
- `test`-aggregate gates had failed. It now depends on the aggregate `CI` job.
568
- - **sdist test-suite failure**: `tests/test_release_contract.py` reads
569
- `.github/workflows/*.yml`, which the sdist `only-include` list omitted, so the
570
- shipped source distribution could not pass its own test suite (13 failures).
571
- The CI workflow files are now part of the sdist.
572
-
573
- ### Added
574
-
575
- - **`npm test` contract suite** (`npm.test.js`): assertions covering
576
- `node --check` parseability, the `cds` module target, argument forwarding, exit
577
- status propagation, the `files` allowlist, npm/Python version agreement, and a
578
- guard that `npm-publish.yml` stays a disabled no-op. CI runs `npm run check`
579
- and `npm test` on every push and pull request; **nothing in CI publishes to
580
- a registry**.
581
- - **`scripts/check_version_lockstep.py`**: machine-enforced agreement across
582
- `pyproject.toml`, `package.json`, `src/cds/_version.py`, `CITATION.cff`, the
583
- runtime `cds.__version__` import, `CHANGELOG.md` and -- with `--dist-dir` --
584
- the built wheel and sdist metadata. `2.1.0` had shipped to PyPI with no
585
- `CHANGELOG.md` entry; that class of drift is now a red build.
586
- - **Wheel/sdist content assertions in CI**: the packaging job now asserts the
587
- exact filename, distribution name, version, `py.typed` marker, sdist root
588
- directory and the absence of forbidden paths (test fixtures, promo media,
589
- `.github`, `site/`) rather than building artifacts and trusting them.
590
- - **Timeouts on every CI job** and per-job least-privilege `permissions:`.
591
-
592
- ### Changed
593
-
594
- - All GitHub Actions references are pinned to full immutable commit SHAs;
595
- previously several workflows used mutable `@v4` / `@v7` / `@v8` tags.
596
- - Branch ruleset for `main` extended in place (not replaced) to require the
597
- aggregate `CI` check plus the `Installed CLI Smoke`, version-discipline,
598
- packaging and npm contract jobs, and to dismiss stale reviews on push.
599
- - npm publishing stays disabled per product decision ("npm is no longer
600
- published"; `npm-publish.yml` is a deliberate no-op). `package.json` is marked
601
- `private`, the npm contract test asserts the workflow stays a no-op, and
602
- nothing in CI uploads to a registry.
603
- - Removed the dead workflow files that main did not already remove:
604
- `wsl-science-runner-smoke.yml` (targeted a self-hosted runner label with zero
605
- registered runners). The retired `public-external-validation-p08-*` experiment
606
- workflows and the one-shot `p08-cancel-noncanonical-runs.yml` /
607
- `tmp-compassion-raw-acquire.yml` jobs were deleted on `main` directly and are
608
- kept deleted here.
609
-
610
- ## [v2.0.1] - 2026-09-29
611
-
612
- Metadata-only patch release for improved PyPI discoverability. No runtime API or numerical behavior changes.
613
-
614
- ### Changed
615
-
616
- - Expanded PyPI keywords and classifiers for reproducibility, uncertainty quantification, sensitivity analysis, dimensional analysis, scientific workflows, ODE/PDE, and related scientific-computing searches.
617
- - Refreshed development lock versions required by the current security audit.
618
- - Normalized repository trailing whitespace required by pre-commit.
619
-
620
-
621
- ### Added
622
-
623
- - **Random Forest classifier** (`cds.ml`): bagged CART trees with
624
- bootstrap resampling and per-split feature randomization (`sqrt`/`log2`
625
- / explicit count), fully deterministic under a seed.
626
- - **Metrics** (`cds.ml`): `accuracy`, `confusion_matrix`,
627
- `precision_recall_f1`, `macro_prf`, regression `mse`/`mae`/`r2_score`,
628
- and tie-aware rank-based `roc_auc`.
629
- - **Cross-validation** (`cds.ml.model_selection`): `k_fold_indices` and
630
- `cross_val_score` over the shared estimator interface.
631
- - **Interpolation module** (`cds.interpolate`): `interp1d` (linear /
632
- nearest) and `interp2d` (bilinear on regular grids).
633
- - **SVD** (`cds.math_utils`): one-sided Jacobi decomposition with
634
- `svd`, `rank` and `condition_number`; full U/Vt factors.
635
- - **STFT / spectrogram** (`cds.signals`): Hann/Hamming windows, framed
636
- zero-padded transforms reusing the radix-2 FFT, `STFTResult`.
637
- - **Gradient Boosting classifier** (`cds.ml`): logistic-loss boosted
638
- regression trees with Newton leaf values; binary labels.
639
- - **Bootstrap confidence intervals** (`cds.stats`): percentile-method
640
- `bootstrap_ci` and two-sample `bootstrap_diff_ci`.
641
- - **Metropolis-Hastings sampler** (`cds.montecarlo`): 1-D random-walk
642
- MCMC with burn-in/thinning and acceptance-rate reporting.
643
- - **Symplectic integrators** (`cds.diffeq`): semi-implicit Euler and
644
- velocity Verlet with forward/backward integration.
645
- - **Constrained optimization** (`cds.optimization`): projected gradient
646
- descent for box bounds and quadratic-penalty constrained solves.
647
- - **Hypergeometric & negative-binomial distributions**
648
- (`cds.probability`), pmf + cdf for both.
649
- - **TF-IDF ranked retrieval** (`cds.knowledge`): `rank_tfidf` across
650
- concepts and notes with smoothed idf.
651
- - **Haar wavelet transform** (`cds.signals`): `dwt` / `idwt` /
652
- `dwt_multi_level`, orthonormal with perfect reconstruction.
653
- - **PDE solvers** (`cds.pde`): explicit FTCS heat equation (Dirichlet /
654
- Neumann, stability-guarded) and wave equation (CFL-guarded).
655
- - **Gaussian Naive Bayes** (`cds.ml`): log-space scoring with variance
656
- smoothing.
657
- - **Correlation-mining engine** (`cds.hypothesis`): `mine_correlations`
658
- turns numeric datasets into statistically tested, falsifiable
659
- `Hypothesis` objects.
660
- - **Power analysis** (`cds.stats`): `power_t_test`,
661
- `power_proportion_test` and `required_n_per_group` sample-size solver.
662
- - **VotingClassifier** (`cds.ml`): hard (majority vote) and soft
663
- (averaged probabilities) ensembles over the shared estimator interface.
664
- - Four new runnable demos under `examples/`: interpolation, PDE,
665
- ensemble showcase and the end-to-end discovery pipeline.
666
- - **PCA end-to-end demo** (`examples/pca_demo.py`): scaling vs raw
667
- variance comparison, component selection, 2-D ASCII projection,
668
- reconstruction error and train/test discipline, with a matching
669
- tutorial (`docs/tutorials/pca_demo.md`).
670
- - **ML correctness reference table** (`scripts/verify_ml_reference.py`,
671
- `docs/ml_reference.md`), LogisticRegression, DecisionTree, KMeans,
672
- PCA and LinearRegression checked against scikit-learn 1.9.0 outputs
673
- on a fixed seeded dataset; one-command, dependency-free verification.
674
-
675
- ### Changed
676
-
677
- - `DecisionTreeClassifier` now accepts `max_features` and `seed` for
678
- random-forest-style split randomization (default behavior unchanged).
679
- - The README now displays the sklearn-parity badge and links the ML
680
- Reference table. (The matching `ml-reference` CI job is prepared but
681
- not yet applied. It needs a push from a token with the `workflow`
682
- OAuth scope; see the `backup/pre-reorder` branch.)
683
-
684
- ## [v2.0.0] - 2026-09-05
685
-
686
- Scientific workflow platform release. Reorganises the project from a numerical
687
- methods library into a layered system that separates computation, analysis,
688
- scientific assurance, orchestration, and data handling.
689
-
690
- ### Added
691
-
692
- - Uncertainty propagation, provenance capture, and tool discovery.
693
- - Dimensional analysis, domain checks, and scalable data I/O.
694
- - Scientific adapters, sensitivity analysis, and tool orchestration.
695
- - CLI catalog refreshed for the expanded module set.
696
-
697
- ### Changed
698
-
699
- - The project is organised into explicit layers (compute / analysis /
700
- assurance / orchestration / data) with dependencies pointing downward.
701
- - Release pipeline enforces a single publish authority.
702
-
703
- ## [v1.6.2] - 2026-08-23
704
-
705
- Patch release carrying the PyPI deprecation tombstone for the former
706
- `cognitive-discovery-system` distribution name, pointing users at
707
- `scientific-computing-system`. No API change; the import name stayed `cds`.
708
-
709
- ## [v1.6.1] - 2026-08-21
710
-
711
- A **patch** release completing the JSON round trip for core data models.
712
-
713
- ### Added
714
-
715
- - **`cds.core`**: `Hypothesis.from_dict()`: the inverse of `to_dict()`.
716
- CLI/JSON output can now be re-imported: enum strings are coerced back to
717
- `Domain` / `HypothesisStatus`, ISO-8601 timestamps are parsed, and missing
718
- optional keys fall back to constructor defaults. Invalid `status` values
719
- raise `ValueError`.
720
-
721
- ### Changed
722
-
723
- - Internal layering cleanup: shared special-function kernels moved to their
724
- single home (`cds.math_utils.special`) so lower-level packages never depend
725
- on higher-level ones; a suite-level import-direction guard enforces this.
726
- - `cds.cli` is now a package (`_style` / `_handlers` / `_parser`) with
727
- identical behaviour; refreshed module descriptions in `cds modules`.
728
-
729
- ## [v1.6.0] - 2026-08-21
730
-
731
- A **minor** release deepening the ML, probability, ODE, and optimization
732
- toolkits toward scikit-learn / SciPy teaching parity, still zero runtime
733
- dependencies, still 100% blended coverage.
734
-
735
- ### Added
736
-
737
- - **`cds.ml`**: `KNeighborsClassifier` / `KNeighborsRegressor` (brute-force,
738
- deterministic tie-breaking), `KMeans` (k-means++ seeding, seeded),
739
- `DecisionTreeClassifier` (CART + Gini), `LogisticRegression` (stable-BCE
740
- gradient descent, optional L2), `LinearRegression` (closed-form vector OLS
741
- via normal equations), `PCA` (cyclic Jacobi eigen-solver, transform /
742
- inverse_transform), `StandardScaler`, `train_test_split` (seeded)
743
- - **`cds.probability`**: chi-square and Student-t distributions
744
- (`chi2_pdf/cdf/ppf`, `t_pdf/cdf/ppf`), `gamma_pdf` + `sample_gamma`
745
- (Marsaglia–Tsang with shape<1 boost), `beta_pdf` + `sample_beta`
746
- (exact gamma-ratio identity)
747
- - **`cds.diffeq`**: implicit stiff solvers: `backward_euler`,
748
- `trapezoid_method` (Crank–Nicolson) and their `_system` variants; unified
749
- θ-method core with Newton iteration over analytic or central-difference
750
- Jacobians via the shared PLU solver
751
- - **`cds.optimization`**: `nelder_mead` simplex (degenerate-simplex and
752
- symmetric false-convergence guards), `simulated_annealing` (Metropolis rule,
753
- box bounds, seeded)
754
- - **`cds.stats`**: nonparametric tests: `mann_whitney_u` and
755
- `wilcoxon_signed_rank` with tie/zero corrections (normal approximation)
756
-
757
- ### Fixed
758
-
759
- - Test-suite pyplot figures are now closed per test, silencing matplotlib's
760
- "more than 20 figures" memory warning in long sessions
761
-
762
- ### Changed
763
-
764
- - README "Why CDS?" pitch strengthened with proof numbers and a cross-domain
765
- snippet; stale counts/versions synced across metadata (19 modules)
766
-
767
- ## [v1.5.0] - 2026-07-20
768
-
769
- A **minor** release expanding algorithms across graph theory, Monte Carlo,
770
- linear algebra, and CLI, still zero runtime dependencies.
771
-
772
- ### Added
773
-
774
- - **`cds.graph`**: `degree`, `connected_components`, `bellman_ford`,
775
- `floyd_warshall`, `prim_mst`
776
- - **`cds.montecarlo`**: `mc_expectation`, `hit_or_miss` (2-D area estimation)
777
- - **`cds.math_utils`**: `vector_norm`, `frobenius_norm`, `matrix_trace`
778
- - **CLI**: `cds integrate <sin|cos|exp|x2|unit> --a --b -n --method`
779
-
780
- ## [v1.4.0] - 2026-07-20
781
-
782
- A **minor** release expanding core scientific APIs and CLI ergonomics.
783
- Zero runtime dependencies preserved.
784
-
785
- ### Added
786
-
787
- - **`cds.probability`**: CDFs (`gaussian_cdf`, `uniform_cdf`, `exponential_cdf`),
788
- `geometric_pmf`, samplers (`gaussian_sample` Box–Muller, `exponential_sample`,
789
- `poisson_sample` Knuth)
790
- - **`cds.stats`**: `spearman_correlation` (midranks), `percentile`, `z_scores`
791
- - **`cds.scientific`**: constants `epsilon_0`, `g`, `mu_0`; formulas
792
- `coulomb_force`, `centripetal_acceleration`, `pendulum_period`, `doppler_frequency`
793
- - **CLI**: `cds stats <nums>`, `cds sample <dist> -n N --seed …`
794
-
795
- ### Changed
796
-
797
- - `cds info` no longer hardcodes a stale test count; module list includes modeling/knowledge/nlp
798
-
799
- ## [v1.3.2] - 2026-07-20
800
-
801
- A **patch** release expanding the optional ``cds[plot]`` surface.
802
-
803
- ### Added
804
-
805
- - **`cds.plot` charts**: `plot_multi_series`, `plot_scatter`, `plot_regression`
806
- (OLS via `cds.stats`), `plot_power_spectrum` (via `cds.signals`),
807
- `plot_seasonal_decompose` (4-panel), `plot_heatmap`, `plot_loss`,
808
- `save_figure(..., close=)` helper; histogram gains ``density=``
809
- - **CLI**: `cds plot … --kind series|hist|acf --file out.png`
810
-
811
- ### Changed
812
-
813
- - Docs / Cookbook / demo updated for the expanded plot API
814
-
815
- ## [v1.3.1] - 2026-07-20
816
-
817
- A **patch** release. Fixes the console entry point so `cds` works after a
818
- plain PyPI install.
819
-
820
- ### Fixed
821
-
822
- - **`[project.scripts]`**: entry point was `cds.cli:app` but the CLI exports
823
- `main` (argparse). Installing from PyPI then raised
824
- `ImportError: cannot import name 'app' from 'cds.cli'`. Now points to
825
- `cds.cli:main`. `python -m cds` was already correct.
826
-
827
- ## [v1.3.0] - 2026-07-20
828
-
829
- A **minor** release focused on **visualization and ergonomics**. Adds the
830
- optional ``cds[plot]`` matplotlib extra, a CLI PNG export path, a companion
831
- notebook, and documentation. The zero-dependency core is unchanged: matplotlib
832
- is only imported when a plot function runs (or when ``cds plot --file`` is
833
- used).
834
-
835
- ### Added
836
-
837
- - **`cds.plot` optional package** (`src/cds/plot/`):
838
- - `plot_series`, `plot_histogram`, `plot_waveform`, `plot_spectrum`
839
- - `plot_acf` / PACF stems via `cds.stats` time-series helpers
840
- - `plot_optimization_path` for 2-D optimizer trajectories
841
- - Lazy matplotlib backend with install-hint `ImportError`
842
- - **Extra**: `pip install scientific-computing-system[plot]` (also in `[all]`)
843
- - **CLI**: `cds plot 1,2,3 --file out.png` saves a PNG when matplotlib is
844
- installed; without `--file` the existing ASCII terminal plot remains
845
- - **Examples**: `examples/plot_demo.py`, `examples/plotting_notebook.ipynb`
846
- - **Docs**: Cookbook matplotlib section, API reference for `cds.plot`, README /
847
- module tables, ROADMAP v1.3.0 track
848
-
849
- ### Changed
850
-
851
- - CI main matrix installs `.[pandas,plot]` so optional bridges stay at 100%
852
- coverage; minimal-deps job omits `cds/plot/*` like `pandas_io`
853
- - PyPI description mentions optional matplotlib plotting
854
-
855
- ## [v1.2.3] - 2026-06-29
856
-
857
- A **patch** release. Fixes the release pipeline that silently broke every
858
- publish since v1.1.8.
859
-
860
- ### Fixed
861
-
862
- - **Release workflow (`release.yml`)**: removed an invalid
863
- `administration: write` entry from the `sync-about` job's `permissions:`
864
- block. `administration` is not a valid `permissions:` key, so GitHub
865
- rejected the entire workflow file as a "workflow file issue" before any
866
- job could start, failing in 0s and leaving v1.1.9 onward without a PyPI
867
- upload or GitHub Release. The About-sync step is now best-effort
868
- (`continue-on-error: true`) since `gh repo edit` needs an admin REST
869
- scope the default `GITHUB_TOKEN` can't grant; the repo description is
870
- synced by hand on release.
871
-
872
- ## [v1.2.2] - 2026-06-29
873
-
874
- A **patch** release. No code changes. Documentation-only refresh.
875
-
876
- ### Changed
877
-
878
- - **README: removed pictographic emoji** from the top navigation row, the
879
- callout blocks, the "Support the project" section heading, and the trailing
880
- sign-off. Em dashes are preserved. Brings the README in line with the
881
- emoji-free house style already applied to the docs and live PR bodies.
882
- - **`.gitignore`: ignore local promo-GIF QA scratch** (audit/compare/measure
883
- scripts under `scripts/_*.py` and extracted frames under `assets/_qa_*/`),
884
- which are one-off diagnostic tooling and were never meant to ship.
885
-
886
- ## [v1.2.1] - 2026-06-28
887
-
888
- A **patch** release. No code changes. Metadata-only refresh to improve
889
- PyPI discoverability.
890
-
891
- ### Changed
892
-
893
- - **Strengthened PyPI `description`**: the short one-liner now names all 18
894
- domain modules (quantum circuits, ML, NLP, signal processing, optimization,
895
- statistics & time-series, ODE solvers, Monte Carlo, symbolic math, knowledge
896
- graphs, hypothesis generation) and states the zero-runtime-dependency
897
- guarantee. Improves search-result relevance on PyPI.
898
- - **Expanded `keywords`** from 12 to 20 entries, aligning them with the GitHub
899
- repository topics (added `machine-learning`, `nlp`, `numerical-integration`,
900
- `knowledge-graph`, `symbolic-math`, `data-analysis`, `physics`,
901
- `hypothesis-generation`, `numerical-methods`; dropped the redundant `fft`
902
- in favour of the broader `signal-processing`).
903
-
904
- ## [v1.2.0] - 2026-06-25
905
-
906
- A **minor** release. The theme is **horizontal expansion + hardening**: three
907
- new domain features (time-series analysis, signal-filter design, 2-D
908
- quadrature), an optional pandas interop extra, and a documentation overhaul
909
- (Cookbook, Architecture guide, expanded Tour). Plus numerical-stability fixes
910
- and a no-behavior-change refactor of the two largest source files.
911
-
912
- No existing public API is removed or renamed; the `cds[pandas]` adapter is
913
- gated behind an optional extra so the zero-dependency core is untouched.
914
-
915
- ### Added
916
-
917
- - **`cds.stats`: time-series analysis** (`src/cds/stats/time_series.py`):
918
- - `moving_average`, `exponential_smoothing`, `difference`, `seasonal_decompose`
919
- - `autocorrelation_function` (sample ACF), `partial_autocorrelation_function` (PACF)
920
- - `kpss_statistic` (stationarity test) and `ljung_box` (autocorrelation test),
921
- both returning result objects with `.statistic` / `.p_value`
922
- - Exported from the top-level `cds.stats` namespace.
923
- - **`cds.signals`: filter design** (`src/cds/signals/filters.py`):
924
- - `butter_lowpass(order, cutoff)`: Butterworth IIR low-pass coefficient design
925
- - `apply_filter(signal, coeffs)`: direct-form IIR application
926
- - `moving_median(signal, window)`: order-statistic denoiser (edge-preserving)
927
- - **`cds.numerical_integration`: 2-D quadrature** (`src/cds/numerical_integration/`):
928
- - `simpson_2d(f, ax, bx, ay, by, nx, ny)`: 2-D tensor-product Simpson rule
929
- - `gaussian_quadrature_2d(f, ax, bx, ay, by, n)`: 2-D tensor-product Gauss-Legendre
930
- - **`cds[pandas]` optional extra** (`src/cds/data_analysis/pandas_io.py`):
931
- - `to_dataframe(data_set)` / `from_dataframe(df)` round-trip a `DataSet` to/from
932
- a `pandas.DataFrame`, guarded so importing `cds` never requires pandas.
933
- - Declared as an optional dependency in `pyproject.toml` (`pandas = {version = ...}`).
934
- - **Documentation**:
935
- - **`docs/cookbook.md`**: a new problem-oriented recipe book (~48 recipes, one
936
- per concrete task), verified end-to-end against the real API by
937
- `_verify_cookbook.py`.
938
- - **`docs/ARCHITECTURE.md`**: layered module dependency graph and data flow.
939
- - **Tour of Numerical Methods** expanded with 2-D quadrature, time-series, and
940
- filter-design stops.
941
- - `docs/index.md` Quick Navigation now links the Cookbook, Tour, and Architecture.
942
-
943
- ### Changed
944
-
945
- - **`cds.modeling` refactor**: `expression.py` (708 lines) split into
946
- `_base.py` (AST base classes, visitors) and `_nodes.py` (operator/leaf node
947
- types). Pure reorganization; no public symbols moved or renamed.
948
- - **`cds.stats` refactor**: distribution functions (normal/t/chi²/F CDFs and
949
- inverses) extracted from `hypothesis_tests.py` into the private
950
- `_distributions.py`, with `__all__` declared so the re-exports pass
951
- `mypy --strict`.
952
-
953
- ### Fixed
954
-
955
- - **`cds.math_utils.linalg`: numerical stability of pivoting.** Pivoting now
956
- uses a scale-relative threshold (`max(|row|) * epsilon`) instead of a fixed
957
- absolute epsilon, and rejects exact-zero pivots at sub-normal matrix scales.
958
- Prevents spurious singular-matrix errors and mis-pivoting on
959
- small-magnitude matrices. No change to well-scaled inputs.
960
- - **`cds.stats`**: `__all__` declared so the `_distributions` re-exports are
961
- recognized as intentional public surface under `mypy --strict`.
962
- - **Tests**: stabilized a flaky mean-homogeneity property test by anchoring on
963
- an absolute tolerance instead of a relative one.
964
-
965
- ## [v1.1.9] - 2026-06-24
966
-
967
- ### Minor — effect-size measures for the statistics & hypothesis stack
968
-
969
- A backward-compatible feature release. Adds standardized **effect-size**
970
- measures to `cds.stats` so users can report the *magnitude* of an effect
971
- alongside its significance, closing the long-standing gap where a
972
- hypothesis test answered *"is there an effect?"* but not *"how large?"*.
973
- No existing API or behavior changes; all prior tests remain green.
974
-
975
- ### Added
976
-
977
- - **`cds.stats`: effect-size measures** (`src/cds/stats/hypothesis_tests.py`):
978
- - `cohens_d(group_a, group_b)`: Cohen's *d* standardized mean difference
979
- between two samples (pooled-SD denominator).
980
- - `eta_squared_from_f(f, df1, df2)`: η² proportion of variance explained
981
- by group membership, derived from a one-way ANOVA *F* statistic.
982
- - `cramers_v(contingency_table)`: Cramér's *V* association strength for
983
- an *r* × *c* contingency table (χ²-based, normalized to `[0, 1]`).
984
- All three functions are exported from the top-level `cds.stats` namespace and
985
- documented in the tutorial (`docs/tutorials/hypothesis_tests_demo.md`).
986
- - **Tutorial section**: *"Effect sizes"* walkthrough in
987
- `hypothesis_tests_demo.md` showing how `cohens_d` / `cramers_v` pair with
988
- the existing `t_test` / `chi_square_independence` tests.
989
- - **Getting-started snippets** (EN + TR) and `docs/index.md` now surface the
990
- effect-size functions in the Python-API quick-start and module table.
991
-
992
- ### Documentation
993
-
994
- - README module table, `docs/index.md` Key Features & module description,
995
- and the EN/TR getting-started guides now mention effect-size support.
996
-
997
- ## [v1.1.8] - 2026-06-21
998
-
999
- ### Patch — ODE backward integration bug fix
1000
-
1001
- A user-facing **bug-fix release**. Forward integration is byte-identical
1002
- to v1.1.7; only the previously-broken `t_end < t0` case changes behavior.
1003
- Includes corrected deep-verification scripts and a docs sync, no new
1004
- modules, no API additions.
1005
-
1006
- ### Fixed
1007
-
1008
- - **`diffeq.solvers`: backward integration silently returned only the
1009
- initial value.** The fixed-step (`euler`, `rk4`, `midpoint`) and
1010
- adaptive (`rk45`) ODE solvers, plus `solve_system`, used a forward-only
1011
- loop guard `while t < t_end - LOOP_EPSILON`. When `t_end < t0` the
1012
- guard was immediately `False`, so the solvers did nothing and returned
1013
- only `y0`. The integration direction is now derived from
1014
- `copysign(1.0, t_end - t0)` and applied as
1015
- `direction * min(dt, abs(t_end - t0))`; `dt` stays an unambiguous
1016
- positive magnitude and the loop guard becomes
1017
- `(t_end - t) * direction > LOOP_EPSILON`. A zero-length span
1018
- (`t_end == t0`) still skips the loop because `copysign(1, 0) == +1`.
1019
- For `rk45`, step size is tracked as an always-positive `h_mag` so the
1020
- shrink/grow/snap logic keeps its forward semantics in either direction.
1021
- 7 new `TestBackwardIntegration` regression tests cover all five
1022
- solvers.
1023
-
1024
- - **`hypothesis.generator`: confidence overflow past `n >= 12`.** The
1025
- generated-confidence formula `0.45 + i*0.05` overflowed the
1026
- `Hypothesis.confidence` `le=1.0` constraint for 12+ hypotheses,
1027
- raising `ValidationError`. Now clamped to `min(0.9, 0.4 + i*0.05)`.
1028
-
1029
- ### Changed (verification tooling)
1030
-
1031
- - **`scripts/verify_d1_numerics.py`, `verify_d2_edge_cases.py`,
1032
- `verify_d4_hypothesis.py`**, stale reference values/thresholds that
1033
- produced spurious failures against correct code: D1.3 Romberg
1034
- monotone-decrease check only asserted above `1e-13`; D1.4 RK45
1035
- singularity now uses `t_end=2.0` (past the pole) so `RuntimeError` is
1036
- genuinely triggered; D1.7/D1.2 odd-degree Gauss-Legendre exact
1037
- integral corrected to `0`; Simpson `O(h^4)` thresholds loosened to
1038
- match the method's order; D4.2 confidence expectation updated to the
1039
- clamped formula. All three scripts now report **0 failures**.
1040
-
1041
- ### Documentation
1042
-
1043
- - README "recent improvements" → v1.1.8 ODE fix entry; ROADMAP marks
1044
- hatch-vcs / git-cliff as tried-and-abandoned with the real rollback
1045
- reasons; SECURITY supported-versions refresh; dashboard UX
1046
- touch-ups; nav/cross-ref drift. **No code or behavior changes.**
1047
-
1048
- ## [v1.1.7] - 2026-06-20
1049
-
1050
- ### Patch — PEP 639 SPDX license metadata
1051
-
1052
- A maintenance release with **no API or behavior changes**. Standardizes
1053
- the license declaration so it is recognized as a valid SPDX identifier
1054
- both on PyPI and in package metadata, and removes drift-prone
1055
- hardcoded numbers from the README.
1056
-
1057
- ### Changed
1058
-
1059
- - **`pyproject.toml`**: adopted [PEP 639](https://peps.python.org/pep-0639/):
1060
- replaced the legacy `license = {text = "MIT"}` table form with the
1061
- SPDX `license = "MIT"` expression plus `license-files = ["LICENSE"]`.
1062
- The wheel/sdist METADATA now emit `License-Expression: MIT` and
1063
- `License-File: LICENSE`, which PyPI and GitHub recognize as a valid
1064
- SPDX id (the old table form was not parsed, so the license read as
1065
- unrecognized). Removed the now-redundant `License :: OSI Approved ::
1066
- MIT License` classifier (deprecated under PEP 639; would trigger a
1067
- metadata warning).
1068
-
1069
- ### Documentation
1070
-
1071
- - **`README.md`**: removed hardcoded, drift-prone numbers (version
1072
- tag, test count, module count) in favor of the existing PyPI / CI /
1073
- codecov badges, so the docs no longer go stale between releases.
1074
-
1075
- ## [v1.1.6] - 2026-06-20
1076
-
1077
- ### Patch — release pipeline fix (OIDC → scoped API token)
1078
-
1079
- A maintenance release with **no API or behavior changes**. Fixes the
1080
- broken automated release pipeline: the previous Trusted Publishing (OIDC)
1081
- path required a PyPI publisher configuration that was never set up, so
1082
- the v1.1.5 tag push failed at the upload step with an `invalid-publisher`
1083
- error. The pipeline now uses a scoped **PyPI API token** (stored as the
1084
- `PYPI_API_TOKEN` repo secret), which is the sole publish authority.
1085
-
1086
- This is the first release actually published by the automated pipeline,
1087
- v1.1.4 and v1.1.5 were uploaded manually before the pipeline existed.
1088
-
1089
- ### Changed
1090
-
1091
- - **`release.yml`**: removed the `id-token: write` permission and the
1092
- Trusted Publishing path; publishes via `pypa/gh-action-pypi-publish`
1093
- with `password: ${{ secrets.PYPI_API_TOKEN }}`. The workflow now also
1094
- creates the GitHub Release (previously done by the local script).
1095
- - **`scripts/publish.py`**: no longer uploads to PyPI or creates the
1096
- GitHub release. It now builds, verified the built version against the
1097
- tag, runs tests, and pushes the tag (which triggers CI). Removed the
1098
- `--skip-release` flag and the local `~/.pypi-token` handling.
1099
- - **`pyproject.toml`**: dropped `twine` from the `[all]` and `[dev]`
1100
- extras (no longer needed locally).
1101
- - **Version bump `1.1.5` → `1.1.6`** in `pyproject.toml`,
1102
- `src/cds/_version.py`, and `CITATION.cff`.
1103
-
1104
- ### Documentation
1105
-
1106
- - **`README.md`** and **`docs/maintenance.md`**: updated the release
1107
- pipeline description to reflect the scoped-API-token flow and
1108
- `release.yml` as the sole publish authority.
1109
-
1110
- ## [v1.1.5] - 2026-06-20
1111
-
1112
- ### Patch — quality, type-safety, test depth, and a 100% coverage gate
1113
-
1114
- A patch release: no API changes, no behavior changes. A coordinated sweep
1115
- of refactoring (type-safety, code deduplication), deeper testing
1116
- (property-based invariants, shared fixtures), expanded documentation
1117
- (tutorials, architecture guide), and a hardening of CI to enforce full
1118
- blended coverage. The result is the cleanest, most thoroughly verified
1119
- release to date: **17 modules, 1230 tests, and 100% code coverage
1120
- (statement + branch)**.
1121
-
1122
- ### Added
1123
-
1124
- - **Python 3.13 support**: added 3.13 to the CI test matrix and the
1125
- `pyproject.toml` classifiers; the full suite is now green on 3.10–3.13.
1126
- - **Shared test fixtures**: `tests/conftest.py` plus `tests/test_core.py`
1127
- centralize reusable fixtures and core invariants, reducing duplication
1128
- across the suite.
1129
- - **Property-based invariant suite (B5)**: a Hypothesis-driven test set
1130
- that exercises numerical invariants (associativity, identity,
1131
- round-trip) over generated inputs, catching edge cases that
1132
- example-based tests miss.
1133
- - **Tutorials for optimization, signals, ML, and statistics (B3)**: new
1134
- guided walkthroughs under `docs/tutorials/` covering the four most-used
1135
- subsystems.
1136
- - **Contributing architecture section (B4)**: `CONTRIBUTING.md` now
1137
- documents the module layout and the data flow between subsystems, with
1138
- stale cross-references fixed.
1139
- - **`examples/modeling_demo.py`**: a new end-to-end example demonstrating
1140
- the modeling workflow referenced by the tutorials.
1141
-
1142
- ### Changed
1143
-
1144
- - **Closed remaining `Any` type escapes**: the last untyped boundaries in
1145
- the core and hypothesis modules now carry concrete types; `mypy --strict`
1146
- stays green.
1147
- - **Generic `OptResult`**: the optimization result type is now generic
1148
- over its scalar type, and the narrowing casts that worked around the old
1149
- concrete signature have been removed.
1150
- - **Deduplicated scalar central-difference**: the scalar central-
1151
- difference implementation that existed in both `calculus` and
1152
- `optimization` is now shared from a single source.
1153
- - **Version bump `1.1.4` → `1.1.5`** in `pyproject.toml`,
1154
- `src/cds/_version.py`, and `CITATION.cff`.
1155
-
1156
- ### CI
1157
-
1158
- - **100% blended coverage gate**: CI now fails unless both statement and
1159
- branch coverage reach 100%, locking in the coverage level as a
1160
- non-regression boundary.
1161
- - **Regenerated benchmark report**: the benchmark report and
1162
- `results.json` were regenerated against the current codebase.
1163
-
1164
- ### Documentation
1165
-
1166
- - **Synced stale test count and coverage**: corrected the documented test
1167
- count (1165 → 1230) and coverage figure (~99.6% → 100%) to match CI.
1168
- - **Roadmap items shipped**: roadmap entries #2 (modeling) and #3
1169
- (knowledge organization) are marked released; the corresponding issues
1170
- are closed.
1171
-
1172
- ## [v1.1.4] - 2026-06-19
1173
-
1174
- ### Patch — documentation, CI, and housekeeping cleanup
1175
-
1176
- A patch release: no API changes, no behavior changes. Removes cosmetic
1177
- distractions (emojis, sprint references) from issue templates and docs,
1178
- fixes CI workflow schemas, and deletes ~3 500 lines of no-op autograd
1179
- shim code that was never exercised at runtime.
1180
-
1181
- ### Changed
1182
-
1183
- - **Issue templates**: removed decorative emojis from
1184
- `bug_report.md`, `config.yml`, and `changelog.yml` for a cleaner,
1185
- more professional appearance.
1186
- - **`.github/labeler.yml`**: migrated to the `actions/labeler` v5
1187
- configuration schema (`triage` → `labels` key).
1188
- - **`.github/workflows/changelog.yml`**: fixed a missing trailing
1189
- newline flagged by lint checks.
1190
- - **Documentation**: stripped sprint-tracking references and
1191
- ephemeral planning files (`docs/superpowers/plans/`,
1192
- `docs/superpowers/specs/`); unified inline-code formatting across
1193
- tutorials and case-study pages.
1194
- - **Removed no-op autograd shims**: deleted `src/cds/nlp/autograd/`
1195
- shim functions (`_grad.py` stubs, pass-through wrappers in
1196
- `ops.py` and `tensor.py`) that were placeholders and never
1197
- participated in any real gradient computation. ~3 500 lines removed.
1198
- - **Examples**: aligned `ruff` formatting in
1199
- `examples/data_analysis_demo.py` and
1200
- `examples/ml_and_viz_demo.py`.
1201
- - **Version bump `1.1.3` → `1.1.4`** in `pyproject.toml`,
1202
- `src/cds/_version.py`, and `CITATION.cff`.
1203
-
1204
- ## [v1.1.3] - 2026-06-19
1205
-
1206
- ### Patch — type-safety cleanup
1207
-
1208
- A patch release: no API changes, no behavior changes. Resolves the final
1209
- block of `mypy --strict` errors so the type checker reports **0 errors
1210
- across 136 files**. No public surface changed; all 1165 tests pass and
1211
- the suite is unchanged.
1212
-
1213
- ### Fixed
1214
-
1215
- - **43 `mypy --strict` errors resolved** across `examples/`, `dashboard/`,
1216
- and `scripts/`. The fixes fall into five categories, none of which
1217
- alter runtime behavior:
1218
- - **`int` → `float` argument types**: numeric literals passed to APIs
1219
- typed as `float` (e.g. integration tolerances, attention scaling)
1220
- now use explicit `float` literals so the call matches the signature.
1221
- - **`Domain` enum usage**: iteration and membership checks against the
1222
- `Domain` enum now go through `Domain.__members__.values()` / explicit
1223
- member references, matching the pattern established in v1.1.2 for
1224
- CodeQL compatibility.
1225
- - **Attention tensor rank**: reshape/transpose calls in
1226
- `examples/nlp_attention_demo.py` and `examples/nlp_mini_gpt_demo.py`
1227
- annotated to reflect the actual tensor rank rather than an
1228
- over-narrow `Any`/scalar guess.
1229
- - **Invariant list widening**: a few demo helper functions that
1230
- return heterogeneous sequences now declare `list[object]` (or the
1231
- specific union) instead of an impossible precise element type.
1232
- - **`Protocol` signature alignment**: a duck-typed callback protocol
1233
- in `scripts/publish.py` had a signature that diverged from its
1234
- concrete implementations; the protocol and call sites now agree.
1235
-
1236
- ### Changed
1237
-
1238
- - **Version bump `1.1.2` → `1.1.3`** in `pyproject.toml` and
1239
- `src/cds/_version.py`.
1240
-
1241
- ## [v1.1.2] - 2026-06-19
1242
-
1243
- ### Patch — security hardening & CodeQL closure
1244
-
1245
- A patch release: no API changes, no behavior changes. Closes the remaining
1246
- CodeQL code-scanning alerts with a fix (not a workaround),
1247
- tightens `main` branch protection, and improves the discoverability of the
1248
- vulnerability-reporting flow. Brings the repo to **0 open** code-scanning
1249
- alerts (22/22 closed: 20 fixed by code, 2 dismissed as documented false
1250
- positives).
1251
-
1252
- ### Security
1253
-
1254
- - **CodeQL `py/non-iterable-in-for-loop`: fix.** Enum iteration
1255
- in `examples/core_demo.py` and `tests/test_hypothesis.py` now uses
1256
- `Domain.__members__.values()` instead of `for x in Domain:`. This is the
1257
- Enum API's standard member-collection view: functionally identical (same
1258
- members, same insertion order, all 1164 tests pass) but the return type
1259
- is an explicitly iterable mapping view that CodeQL's type resolver can
1260
- follow. Previous attempts (idiomatic iteration, direct import from the
1261
- defining module) did not satisfy the analyzer; this does, with no
1262
- camouflage (`list()` wrapping) and no behavior change.
1263
- - **`main` branch protection strengthened.** Added `required_status_checks`
1264
- for `CI` and `CodeQL`, a PR can no longer merge into `main` while those
1265
- checks are red. `enforce_admins` is left disabled so the maintainer
1266
- retains a direct-push path; everything else (linear history, conversation
1267
- resolution, no force-pushes, no deletions) is unchanged.
1268
- - **Security-reporting guidance.** The README now links to `SECURITY.md`
1269
- and the private-advisory flow; the bug-report issue template warns against
1270
- opening public issues for vulnerabilities and redirects to private
1271
- advisories.
1272
-
1273
- ### Changed
1274
-
1275
- - **`CITATION.cff` version refresh.** Two stale `1.1.0` references (root and
1276
- `preferred-citation` blocks) bumped to `1.1.2`. This was missed in v1.1.1.
1277
-
1278
- ## [v1.1.1] - 2026-06-19
1279
-
1280
- ### Patch — supply-chain & CI hardening
1281
-
1282
- A patch release: no API changes, no behavior changes. Strengthens release
1283
- integrity and CI correctness so downstream consumers and contributors get
1284
- verifiable, low-churn workflows.
1285
-
1286
- ### Security
1287
-
1288
- - **CodeQL static analysis** (`codeql.yml`): runs `security-and-quality`
1289
- query pack on every push/PR into `main` plus a weekly schedule; findings
1290
- surface as code-scanning alerts under the Security tab. Complements
1291
- `attest.yml` (which signs release artifacts with build provenance) and
1292
- `dependabot.yml` (dependency CVEs).
1293
- - **README security badge**: live CodeQL status added next to the CI badge.
1294
-
1295
- ### Changed
1296
-
1297
- - **`changelog.yml` made idempotent**: all dispatches now target a single
1298
- fixed branch (`chore/changelog-regen`); `peter-evans/create-pull-request`
1299
- updates the existing open PR instead of opening a duplicate per tag.
1300
- Previously up to 6 stale changelog PRs accumulated; now only one is ever
1301
- open. Also bumped the action `v6 → v7` and added a `concurrency` group to
1302
- serialize simultaneous dispatches.
1303
- - **`benchmarks.yml` respects branch protection**: switched from a direct
1304
- bot push (rejected on protected `main`) to opening a PR via
1305
- `peter-evans/create-pull-request@v7`, so regenerated artifacts merge
1306
- through the normal review flow without breaking protection rules.
1307
-
1308
- ### Removed
1309
-
1310
- - 6 stale auto-generated changelog PRs (#10, #19, #20, #21, #22, #23) and
1311
- their per-tag branches, all superseded by the hand-curated CHANGELOG on
1312
- `main`.
1313
-
1314
- ## [v1.1.0] - 2026-06-19
1315
-
1316
- ### Minor — two new modules (symbolic math + knowledge organization)
1317
-
1318
- A backward-compatible feature release. Adds two new public subpackages
1319
- (`cds.modeling`, `cds.knowledge`) without changing any existing API. The
1320
- platform now spans **17 modules**, **1164 tests**, and **99.59%** coverage.
1321
-
1322
- ### Added
1323
-
1324
- - **`cds.modeling`**: symbolic algebra for equation development:
1325
- - An expression tree (`+`, `-`, `*`, `/`, `**`, unary `-`, variables,
1326
- numbers) built by overloading Python operators on a `Variable`/`Constant`
1327
- AST.
1328
- - Symbolic differentiation (`diff`), algebraic simplification
1329
- (`simplify`), substitution (`subs`), evaluation (`evaluate`), and
1330
- LaTeX export (`to_latex`).
1331
- - A `MathModel` for equation systems with `solve_equation` (Newton-Raphson
1332
- root finding) and `fit_parameters` (least-squares parameter fitting to
1333
- observations).
1334
- - Runnable demo (`examples/modeling_demo.py`) + tutorial.
1335
- - **`cds.knowledge`**: a knowledge-organization layer in three pure-Python,
1336
- dependency-free files:
1337
- - `graph.py`: `Concept`, `Relation` (typed directed edges), and a
1338
- `KnowledgeGraph` with undirected traversal (shortest path via BFS,
1339
- transitive closure, cycle detection), neighbors, and JSON persistence.
1340
- - `notes.py`: `Note` + `Notebook` research notebook with tag and
1341
- concept lookups, and JSON persistence.
1342
- - `retrieval.py`: `search()` producing ranked `SearchResult` hits across
1343
- both concepts and notes (matched field + normalized score).
1344
- - Runnable demo (`examples/knowledge_demo.py`) + tutorial.
1345
- - Both modules are wired into the package `__all__`, the CLI `modules`
1346
- listing, and the API reference (`docs/api.md`).
1347
-
1348
- ### Maintenance
1349
-
1350
- - Docs: resync README, `docs/index.md`, getting-started (EN + TR), and
1351
- CITATION.cff to v1.1.0, module count 16→17, test count 883→1164,
1352
- coverage 99.48%→99.59%. Keep `pyproject.toml` + `src/cds/_version.py`
1353
- lockstepped at 1.1.0.
1354
- - Chore(repo): ignore the `_demo_*.json` runtime artifacts the
1355
- knowledge demo writes next to its script, so a demo run no longer
1356
- dirties the working tree.
1357
-
1358
- ## [v1.0.4] - 2026-06-18
1359
-
1360
- ### Security & Tooling — CI hardening
1361
-
1362
- A follow-up patch to v1.0.3. No behavior changes to the published package;
1363
- fully backward compatible. Adds continuous dependency-vulnerability scanning
1364
- to CI, tightens the type-check configuration, and resynchronizes docs that
1365
- had drifted after v1.0.0.
1366
-
1367
- ### Maintenance
1368
-
1369
- - Chore(ci): add a `pip-audit` job to the CI workflow (`tests.yml`). Runs
1370
- once on the reference cell (Linux + Python 3.12) against the PyPI Advisory
1371
- database. Currently `continue-on-error: true`, the dev/docs/test toolchain
1372
- (jupyter, mkdocs, build, twine, pillow, lxml, ...) carries transitive deps
1373
- with open CVEs unrelated to the published runtime (typer/pydantic/rich,
1374
- which audit clean). Surfacing them every run gives visibility without
1375
- red-flashing the matrix on a fresh advisory.
1376
- - Chore(types): remove the global `ignore_missing_imports = true` from
1377
- `[tool.mypy]`. CDS only depends on PEP 561 typed runtime libs (typer,
1378
- pydantic, rich), all of which resolve cleanly under strict mypy (98 files,
1379
- 0 errors). Dropping the escape hatch means a future un-stubbed dependency
1380
- surfaces a real error instead of being silently typed as `Any`.
1381
- - Chore(repo): delete a stray Windows `nul` artifact left in the working tree.
1382
- - Docs: resync README + `docs/` after v1.0.0: test count 845→878, version
1383
- strings updated, `CITATION.cff` bumped to 1.0.4. Keep `pyproject.toml` +
1384
- `src/cds/_version.py` lockstepped at 1.0.4.
1385
-
1386
- ## [v1.0.3] - 2026-06-18
1387
-
1388
- ### Hygiene — test-suite type correctness
1389
-
1390
- A follow-up patch to v1.0.2. No behavior changes to the published package;
1391
- fully backward compatible. Brings `tests/` to the same mypy baseline as
1392
- `src/` so the full type-check (`mypy src/ tests/`) is green, and resolves
1393
- post-release lint/test/publish findings caught after v1.0.2 shipped.
1394
-
1395
- ### Testing
1396
-
1397
- - Test(types): clear all remaining mypy errors across `tests/` (39 files,
1398
- 0 errors). Fixes list-variance issues (`Parameter <: Tensor`), redundant
1399
- `type: ignore` comments, and intentional error-path `**` operands.
1400
- - Test(benchmarks): isolate benchmark test artifacts: `run_all()` /
1401
- `_write_json()` accept an `output_dir` parameter so `pytest` no longer
1402
- clobbers the committed `benchmarks/results.json`.
1403
-
1404
- ### Maintenance
1405
-
1406
- - Chore(ci): resolve post-1.0.2 lint/test/publish findings (commit 5e429ec).
1407
- - Docs: keep `pyproject.toml` + `src/cds/_version.py` lockstepped at 1.0.3.
1408
-
1409
- ## [v1.0.2] - 2026-06-18
1410
-
1411
- ### Hygiene — test isolation for benchmark artifacts
1412
-
1413
- A follow-up patch to v1.0.1. No behavior changes to the published package;
1414
- fully backward compatible. Resolves a repo-hygiene issue where running the
1415
- benchmark test suite silently clobbered the committed
1416
- `benchmarks/results.json` artifact (and `docs/benchmarks.md`) on every
1417
- `pytest` invocation.
1418
-
1419
- ### Bug Fixes
1420
-
1421
- - Fix(tests): `test_run_all_generates_report` no longer writes into the
1422
- working tree. `run_all()` and `_write_json()` now accept an optional
1423
- `output_dir` parameter; the test passes its `tmp_path`, so the committed
1424
- `benchmarks/results.json` and `docs/benchmarks.md` are never modified by a
1425
- test run. Verified: object hash of `results.json` is byte-identical before
1426
- and after `pytest`.
1427
-
1428
- ### Testing
1429
-
1430
- - Test(benchmarks): added a regression assertion that `results.json` lands
1431
- in `tmp_path` (not `benchmarks/`) after `run_all(output_dir=...)`.
1432
-
1433
- ### Features
1434
-
1435
- - Feat(benchmarks): `run_all(output_dir=None)` and
1436
- `_write_json(record, output_dir=None)`, new optional parameter for
1437
- redirecting artifact output. Defaults preserve existing CLI behaviour.
1438
-
1439
- ## [v1.0.1] - 2026-06-18
1440
-
1441
- ### Maintenance — typed, documented, hardened
1442
-
1443
- A follow-up to the v1.0 stable release focused on packaging quality and
1444
- numerical correctness guarantees. No behavior changes; fully backward
1445
- compatible.
1446
-
1447
- ### Features
1448
-
1449
- - Feat(packaging): declare PEP 561 type information: ship `src/cds/py.typed`
1450
- marker and force-include it in the wheel so downstream users get full
1451
- static type-checking support out of the box.
1452
- - Feat(docs): add "type checked" badge to the README.
1453
-
1454
- ### Testing
1455
-
1456
- - Test(invariants): add `tests/test_numerical_invariants.py`: 32
1457
- property-based numerical invariants across 8 modules (linalg, signals,
1458
- stats, quadrature, quantum, diffeq, monte carlo, probability). Fixed
1459
- seed, fully reproducible, zero new dev dependencies.
1460
-
1461
- ### Documentation
1462
-
1463
- - Docs(api): add docstrings to all 51 previously-undocumented public
1464
- functions identified via AST scan (3 empty-docstring gaps closed).
1465
-
1466
- ### Bug Fixes
1467
-
1468
- - Chore: bump version to 1.0.1.
1469
-
1470
- ## [v1.0.0] - 2026-06-18
1471
-
1472
- ### 1.0 — Stable release
1473
-
1474
- Cognitive Discovery Platform reaches its first stable release. All five
1475
- subsystems of the v1.0 completion spec are implemented, gated, and
1476
- verified: 99.16% statement coverage (845 tests passing), zero mypy
1477
- errors, clean ruff, and a strict mkdocs build.
1478
-
1479
- ### Features
1480
-
1481
- - Feat(nlp): NLP visualisation module: attention heatmap, PCA projection, training curve ([7956597](7956597))
1482
- - Feat(benchmarks): emit results.json with timestamp + git SHA provenance, add CI workflow ([4e18500](4e18500))
1483
-
1484
- ### Testing
1485
-
1486
- - Test(coverage): close NLP edge-case gaps: tensor/ops/optim/bpe/layers/model/attention; reach 99.16% statement coverage ([6f0a487](6f0a487))
1487
- - Style(tests): ruff format cleanup: collapse over-split listcomp, expand train() signature, remove duplicate inline imports ([36f4ee4](36f4ee4))
1488
-
1489
- ### Documentation
1490
-
1491
- - Docs(examples): add 9 module demos + matching tutorials ([9f00fc5](9f00fc5))
1492
- - Docs(api): restructure mkdocs nav, add api.md lead-ins, fix stale test counts ([4cad8be](4cad8be))
1493
- - Docs(nlp): fix griffe warnings: split combined params in docstrings ([3aedff4](3aedff4))
1494
- - Docs(benchmarks): regenerate results.json with current SHA provenance ([69c5a88](69c5a88))
1495
-
1496
- ### Bug Fixes
1497
-
1498
- - Chore: bump version to 1.0.0 + Production/Stable classifier; sync _version.py
1499
-
1500
- ### Other
1501
-
1502
- - Promoted from `Development Status :: 4 - Beta` to `Development Status :: 5 - Production/Stable`.
1503
-
1504
- ## [v0.10.0b1] - 2026-06-17
1505
-
1506
-
1507
- ### Features
1508
-
1509
-
1510
- - Feat(nlp): autograd engine + MiniGPT-from-scratch ([5e0d308](5e0d308))
1511
-
1512
-
1513
- ### Documentation
1514
-
1515
-
1516
- - Docs(changelog): regenerate for v0.9.0b8 (#17) ([2b0a7d3](2b0a7d3))
1517
-
1518
-
1519
- ## [v0.9.0b8] - 2026-06-17
1520
-
1521
-
1522
- ### Features
1523
-
1524
-
1525
- - Feat(nlp): add multi-head attention + transformer block ([4f38cae](4f38cae))
1526
-
1527
-
1528
- ### Documentation
1529
-
1530
-
1531
- - Docs(changelog): regenerate for v0.9.0b7 (#16) ([44ec93c](44ec93c))
1532
-
1533
-
1534
- ## [v0.9.0b7] - 2026-06-17
1535
-
1536
-
1537
- ### Bug Fixes
1538
-
1539
-
1540
- - Fix: catch two more stale surfaces (CITATION.cff, mkdocs api.md) ([b59b6e3](b59b6e3))
1541
-
1542
-
1543
- ### Documentation
1544
-
1545
-
1546
- - Docs(changelog): regenerate for v0.9.0b6 (#15) ([e1244ce](e1244ce))
1547
-
1548
-
1549
- ## [v0.9.0b6] - 2026-06-17
1550
-
1551
-
1552
- ### Bug Fixes
1553
-
1554
-
1555
- - Fix: sync test count 572 to 655 across all surfaces ([952ffe0](952ffe0))
1556
-
1557
-
1558
- ### Documentation
1559
-
1560
-
1561
- - Docs(changelog): regenerate for v0.9.0b5 (#14) ([f7a037b](f7a037b))
1562
-
1563
-
1564
- ## [v0.9.0b5] - 2026-06-17
1565
-
1566
-
1567
- ### Features
1568
-
1569
-
1570
- - Feat(nlp): add cds.nlp module: BPE tokenizer + sinusoidal embeddings ([045b9d1](045b9d1))
1571
-
1572
-
1573
- ### Other
1574
-
1575
-
1576
- - Build: drop hatch-vcs + setuptools_scm, switch to static versioning ([6e04d31](6e04d31))
1577
-
1578
-
1579
- ### Documentation
1580
-
1581
-
1582
- - Docs(changelog): regenerate for v0.9.0b4 (#13) ([da52ee0](da52ee0))
1583
-
1584
-
1585
- ## [v0.9.0b4] - 2026-06-17
1586
-
1587
-
1588
- ### Bug Fixes
1589
-
1590
-
1591
- - Fix: drop stale 'auditor' comment + sync 570 to 572 across docs and cli ([0dcaba6](0dcaba6))
1592
-
1593
-
1594
- ### Documentation
1595
-
1596
-
1597
- - Docs(changelog): regenerate for v0.9.0b4 (#11) ([b1eda78](b1eda78))
1598
-
1599
-
1600
- ## [v0.9.0b3] - 2026-06-17
1601
-
1602
-
1603
- ### Bug Fixes
1604
-
1605
-
1606
- - Fix(docs): include getting-started.tr.md in mkdocs nav; fix broken CONTRIBUTING link ([85316fe](85316fe))
1607
-
1608
- - Fix: bump CITATION.cff top-level version to 0.9.0b2 ([80cc3b4](80cc3b4))
1609
-
1610
- - Fix: bump CITATION.cff top-level version to 0.9.0b2 (was 0.8.5, missed during release) ([adee53c](adee53c))
1611
-
1612
- - Fix: keep cast() in test_legendre (Python 3.10/3.11 mypy needs it, 3.12 ignores) ([bcd20fc](bcd20fc))
1613
-
1614
- - Fix: resolve 34 mypy errors (matrix/fft type unions, plot float types, missing confidence arg, cli.Path) ([eea36a3](eea36a3))
1615
-
1616
- - Fix: type local _legendre import as Callable[[int, float], tuple[float, float]] (cross-Python mypy fix) ([486bad5](486bad5))
1617
-
1618
- - Fix: use # type: ignore[no-any-return] instead of cast() for cross-Python compat ([bd3aaa8](bd3aaa8))
1619
-
1620
-
1621
- ### Other
1622
-
1623
-
1624
- - Build: add setuptools_scm local-scheme config (no-local-version, fallback) ([82d07c9](82d07c9))
1625
-
1626
- - Build: exclude hatch-vcs generated _version.py from ruff ([76760d3](76760d3))
1627
-
1628
- - Build: publish.py ignores hatch-vcs regenerated _version.py in dirty check ([bea5f71](bea5f71))
1629
-
1630
- - Build: setuptools_scm version_scheme=no-guess-dev; fix wheel version regex ([8ccb292](8ccb292))
1631
-
1632
- - Release: v0.9.0b1 - Beta milestone, CI multi-OS, hatch-vcs, git-cliff, attestation ([3e3928f](3e3928f))
1633
-
1634
- - Release: v0.9.0b2 - same code, re-tag to trigger attest workflow (checkout fix) ([c54e900](c54e900))
1635
-
1636
- - Release: v0.9.0b3 - branch protection, threat model, i18n, signed commits guide ([31983fe](31983fe))
1637
-
1638
-
1639
- ### Documentation
1640
-
1641
-
1642
- - Docs(changelog): regenerate for v0.9.0b1 ([44f7823](44f7823))
1643
-
1644
- - Docs(changelog): regenerate for v0.9.0b2 ([404532c](404532c))
1645
-
1646
- - Docs(changelog): regenerate for v0.9.0b3 (#8) ([3a8ef95](3a8ef95))
1647
-
1648
- - Docs(changelog): regenerate for v0.9.0b3 (#9) ([c4fcb9b](c4fcb9b))
1649
-
1650
- - Docs: add threat model, signed commits guide, Why CDS comparison, Turkish i18n; update ROADMAP ([0ba07cf](0ba07cf))
1651
-
1652
- - Docs: update SECURITY.md supported versions (0.6.x → 0.8.x) ([b42cf5f](b42cf5f))
1653
-
1654
-
1655
- ### Styling
1656
-
1657
-
1658
- - Style: pre-commit auto-fix (trailing whitespace, import order, ruff format) ([9adbf5a](9adbf5a))
1659
-
1660
- - Style: pre-commit auto-fix _version.py (add blank line before __version__) ([277b535](277b535))
1661
-
1662
-
1663
- ### Miscellaneous Tasks
1664
-
1665
-
1666
- - Ci: changelog PR action needs explicit base branch (checked out on tag) ([b96d322](b96d322))
1667
-
1668
- - Ci: changelog action checks out main (not tag) to avoid detached HEAD issues ([af3cd12](af3cd12))
1669
-
1670
- - Ci: changelog workflow needs write contents + pull-requests perms ([a319a9f](a319a9f))
1671
-
1672
- - Ci: changelog workflow uses PR instead of direct push (branch protection compat) ([3f593cb](3f593cb))
1673
-
1674
- - Ci: fix attest + changelog workflows (checkout step, detached HEAD push) ([d2c9d6e](d2c9d6e))
1675
-
1676
- - Ci: quote step name with colon (YAML parse error) ([0731ca8](0731ca8))
1677
-
1678
- - Ci: rewrite tests.yml with simple bash conditional (no GitHub conditional parse issues) ([2cc8483](2cc8483))
1679
-
1680
- - Ci: split test step into 2 by matrix (gate vs report-only) - fix missing fi ([9e68ff0](9e68ff0))
1681
-
1682
-
1683
- ## [v0.8.5] - 2026-06-16
1684
-
1685
-
1686
- ### Other
1687
-
1688
-
1689
- - Release: v0.8.5 - cds[all] extras, auto-generated API ref, docs deploy ([12b03b0](12b03b0))
1690
-
1691
-
1692
- ## [v0.8.4] - 2026-06-16
1693
-
1694
-
1695
- ### Other
1696
-
1697
-
1698
- - Release: v0.8.4 - pydantic upgrade ([58ee8d9](58ee8d9))
1699
-
1700
-
1701
- ## [v0.8.3] - 2026-06-16
1702
-
1703
-
1704
- ### Other
1705
-
1706
-
1707
- - Release: v0.8.3 - example guard consistency ([5017680](5017680))
1708
-
1709
-
1710
- ## [v0.8.2] - 2026-06-16
1711
-
1712
-
1713
- ### Other
1714
-
1715
-
1716
- - Release: v0.8.2 - docstrings, knowledge/ removal, CHANGELOG backfill ([f22150c](f22150c))
1717
-
1718
- - Scripts: replace publish.ps1 with pure-Python publish.py ([c7c08e2](c7c08e2))
1719
-
1720
-
1721
- ### Miscellaneous Tasks
1722
-
1723
-
1724
- - Ci: fix pre-commit and coverage gate for stable CI ([ca66c9f](ca66c9f))
1725
-
1726
- - Ci: remove Docs workflow; relax coverage gate; re-enable legacy Pages ([cdcf5d0](cdcf5d0))
1727
-
1728
-
1729
- ## [v0.8.1] - 2026-06-16
1730
-
1731
-
1732
- ### Other
1733
-
1734
-
1735
- - Release: v0.8.1 ([4dc49e2](4dc49e2))
1736
-
1737
-
1738
- ### Documentation
1739
-
1740
-
1741
- - Docs(roadmap): link open enhancement issues #2 and #3 under Longer Term ([ee6103b](ee6103b))
1742
-
1743
- - Docs: mark v0.8.0 as released; move 3 pending perf items to v0.8.1 ([80e6afe](80e6afe))
1744
-
1745
-
1746
- ### Testing
1747
-
1748
-
1749
- - Test: hit 100% statement coverage; keep branch coverage off ([5c606c4](5c606c4))
1750
-
1751
-
1752
- ### Miscellaneous Tasks
1753
-
1754
-
1755
- - Ci(pypi): fix pypi-publish workflow ([8335cb6](8335cb6))
1756
-
1757
- - Ci(scripts): add publish.ps1 for local PyPI releases ([57e81a4](57e81a4))
1758
-
1759
- - Ci: harden repo to 10/10 - pre-commit, lockfiles, coverage gate ([7c3b18f](7c3b18f))
1760
-
1761
- - Ci: remove pypi-publish workflow ([043b7f5](043b7f5))
1762
-
1763
-
1764
- ## [v0.8.0] - 2026-06-16
1765
-
1766
-
1767
- ### Other
1768
-
1769
-
1770
- - Squashed: collapse 108 commits into a single cohesive history ([d4e8aee](d4e8aee))
1771
-
1772
- - Release: v0.8.0 - Performance & Benchmarks ([83211ef](83211ef))
1773
-
1774
-
1775
- <!-- generated by git-cliff -->
1
+ # Changelog
2
+
3
+ All notable changes to **scientific-computing-system** will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [v2.2.8] - 2026-10-17
9
+
10
+ ### Scientific validation fail-closed thresholds
11
+
12
+ - Reject NaN and infinite tolerances for independent-method agreement and conservation.
13
+ - Reject non-finite OOD margins, distribution-drift thresholds, and residual diagnostic limits.
14
+ - Add regression coverage for these parameter-contract failures and align the public
15
+ version tuple with the synchronized release metadata.
16
+
17
+ ## [v2.2.7] - 2026-10-15
18
+
19
+ ### Housekeeping — version lockstep
20
+
21
+ - Release 2.2.7 (2026-10-15): records the production/Stable line against
22
+ which the repository's locked surfaces (codemeta.json, pyproject.toml,
23
+ package.json, `cds --version`) are verified by
24
+ `tests/test_codemeta_version_lockstep.py`.
25
+ - Bumps the npm shim to the same 2.2.7 line so both publish channels ship
26
+ at identical versions, as documented in the README "Install" section.
27
+
28
+ ## [v2.2.6] - 2026-10-13
29
+
30
+ ### Housekeeping — second-round neighbour sweep
31
+
32
+ - `transpose` shares the ragged-input contract the rest of the matrix API has
33
+ held since 2.2.5. It indexed only the leading row's width, so a short row
34
+ lost entries silently (`[[1.0],[2.0,3.0]]` became `[[1.0, 2.0]]`): the
35
+ result described a matrix nobody supplied. It now fails closed through the
36
+ same `_require_rectangular` check `mat_mul` and Cholesky use.
37
+ - Geometric PMF boundary pinned: `geometric_pmf(0, p)` is 0 (no trial counted
38
+ 1-based), and extreme `(k, p)` stays finite.
39
+ - `poisson_pmf(0, 0)` is 1 and the log-space PMFs were probed at their
40
+ previously-crashing inputs; no remaining overflow class found in the
41
+ probability module.
42
+
43
+ ## [v2.2.5] - 2026-10-12
44
+
45
+ ### Housekeeping — audit hardening
46
+
47
+ - Closes the findings of the full-repository audit: patched the concrete
48
+ defects (correctness, fail-closed behaviour, platform independence),
49
+ wired every standalone guard into CI, removed dead or duplicated code
50
+ paths, and pinned every doc claim to a test so it cannot silently
51
+ drift again. Regression tests fail without the corresponding fix.
52
+
53
+ ## [Unreleased]
54
+
55
+ ### Distribution status of 2.2.2 — read this before assuming npm has it
56
+
57
+ The two registries are **not** in the same state for 2.2.2.
58
+
59
+ | Registry | `2.2.2` | Build attestation |
60
+ |---|---|---|
61
+ | **PyPI** `scientific-computing-system` | **published** | **PEP 740 provenance present** |
62
+ | **npm** `scientific-computing-system` | **NOT published** | none — the version does not exist on npm |
63
+
64
+ PyPI 2.2.2 is live and carries a PEP 740 attestation. Verified against the live
65
+ registries on 2026-10-05: the PEP 740 per-file provenance endpoint returns
66
+ **HTTP 200** for both files.
67
+
68
+ ```
69
+ curl -sS -o /dev/null -w '%{http_code}\n' \
70
+ https://pypi.org/integrity/scientific-computing-system/2.2.2/scientific_computing_system-2.2.2-py3-none-any.whl/provenance # 200
71
+ curl -sS -o /dev/null -w '%{http_code}\n' \
72
+ https://pypi.org/integrity/scientific-computing-system/2.2.2/scientific_computing_system-2.2.2.tar.gz/provenance # 200
73
+ ```
74
+
75
+ npm 2.2.2 does not exist. The published npm versions remain `1.0.0`, `2.2.0` and
76
+ `2.2.1`. Nothing about the npm launcher is broken — the publish is blocked on a
77
+ one-time npmjs.com registration, described next.
78
+
79
+ ### Pending: register the npm trusted publisher (one-time, maintainer, in a browser)
80
+
81
+ npmjs.com has **no trusted publisher** configured for the package
82
+ `scientific-computing-system`. Until one exists, the OIDC path cannot complete a
83
+ publish, and npm publishes no provenance for this package.
84
+
85
+ The coordinates to enter on npmjs.com → package `scientific-computing-system` →
86
+ **Settings → Trusted Publisher → GitHub Actions**:
87
+
88
+ | Field | Value |
89
+ |---|---|
90
+ | Organization or user | `Furox-Art` |
91
+ | Package | `scientific-computing-system` |
92
+ | Workflow filename | `npm-publish.yml` |
93
+ | Environment name | `npm` |
94
+ | Allowed actions | **`npm publish`** — must be enabled, see the warning below |
95
+
96
+ **The allowed-actions field is not optional in practice.** npm's current UI grants
97
+ `npm stage publish` by default on newly created configurations and makes direct
98
+ `npm publish` **opt-in**. This repository's workflow calls `npm publish` directly,
99
+ so registering the publisher *without* also allowing `npm publish` will leave the
100
+ publish failing — with a permission error this time rather than a 404.
101
+
102
+ The same registration from the CLI, using the maintainer's own npm login and 2FA:
103
+
104
+ ```
105
+ npm trust github --file npm-publish.yml \
106
+ --repo Furox-Art/scientific-computing-system --env npm --allow-publish
107
+ ```
108
+
109
+ ### The publish mode default is unchanged, and was never set to token
110
+
111
+ The mode is the `workflow_dispatch` input `use_token_fallback`, whose default is
112
+ `false` — that is **OIDC**. There is no `npm_publish_mode` variable; the repository
113
+ has **no Actions variables at all** (none at repository or organization scope), and
114
+ `npm_publish_mode` appears nowhere in the tree. Nothing needs to be switched back:
115
+ OIDC is already the default, and token mode remains an explicit per-run opt-in.
116
+
117
+ `NPM_TOKEN` does still exist as a repository secret. It is what token mode would
118
+ use, and it should be deleted once the trusted publisher is registered and the
119
+ first OIDC publish has succeeded.
120
+
121
+ ### Fixed: a 404 from npm no longer reads as "already published"
122
+
123
+ `npm publish` answered
124
+
125
+ ```
126
+ npm error 404 The requested resource 'scientific-computing-system@2.2.2' could not
127
+ be found or you do not have permission to access it.
128
+ ```
129
+
130
+ on runs 37268729425 and 37269325567, and that single line cannot distinguish the
131
+ two real causes. npm deliberately does not tell an unauthenticated caller whether a
132
+ package exists, so **an unregistered trusted publisher is reported as 404, not as
133
+ 401 or 403.**
134
+
135
+ Two failure surfaces were making that expensive to diagnose, and both now say so
136
+ out loud. Neither changes what the workflow does; both only change what it prints.
137
+
138
+ - **The publish step** now names the real cause when npm returns 404, states that
139
+ the package exists and the version is absent, prints the npmjs.com fields above,
140
+ and calls out the `npm publish` allowed-action requirement. A rejected or absent
141
+ token looks different (401, or `ENEEDAUTH`), and the step says that too.
142
+ - **The version-existence gate** now warns, at the point where it would otherwise
143
+ tell someone to bump the version, that a 404 also means "unauthorized". Bumping
144
+ to escape a 404 consumes a release number on both registries and still will not
145
+ publish while the publisher is unregistered.
146
+
147
+ Worth recording precisely: in **both** runs the version gate **passed**. The
148
+ tarball built, provenance was signed and submitted to the Sigstore transparency
149
+ log, and only the `PUT` failed. So both runs did prove the authentication failure,
150
+ and the fix is the registration above — not a version bump.
151
+
152
+ ## [v2.2.4] - 2026-10-12
153
+
154
+ ### Housekeeping — release alignment
155
+
156
+ - Publishes the post-2.2.3 repository state (single-shot automatic npm
157
+ publishing, #165) to PyPI and npm: the 2.2.3 upload predates that commit, so
158
+ both registries were one commit behind `main`. No behavioural change.
159
+
160
+ ## [v2.2.3] - 2026-10-05
161
+
162
+ This release exists to exercise the OIDC trusted-publish path, now that the
163
+ npmjs.com trusted publisher for `scientific-computing-system` is registered.
164
+
165
+ The previous npm 2.2.2 was published in token mode and therefore carries no
166
+ attestation. Nothing about the launcher changed: `src/` is untouched since
167
+ 2.2.2, and the only source change in this release is the version string itself.
168
+
169
+ ## [v2.2.2] - 2026-10-05
170
+
171
+ Clears the last 17 open CodeQL alerts in this repository. None of them was a
172
+ security vulnerability, and **none was a logic defect** — no discarded result, no
173
+ missing `return`. Nothing is suppressed: there is no `# nosec`, no path exclusion
174
+ and no `codeql.config` entry.
175
+
176
+ ### Behaviour change
177
+
178
+ **One, and it is a removal:** the private path `cds.cli._parser._build_parser` no
179
+ longer resolves.
180
+
181
+ `_build_parser` was an alias for `build_parser`, kept for backwards
182
+ compatibility. It was defined in `cds.cli._parser` but imported and re-exported by
183
+ `cds.cli.__init__`, so within its own module it was genuinely unreferenced —
184
+ which is exactly what `py/unused-global-variable` reported. The assignment has
185
+ moved to `cds.cli.__init__`, beside its only consumer and inside the `__all__`
186
+ that already exports it.
187
+
188
+ - `cds.cli._build_parser` is unchanged: still present, still in `__all__`, still
189
+ the same object as `cds.cli.build_parser`. This is the documented
190
+ backwards-compatibility surface and it keeps working.
191
+ - `cds.cli._parser._build_parser` is gone. Nothing in this repository referenced
192
+ it and the name is underscore-private, but a downstream script that reached
193
+ into the private submodule would break.
194
+
195
+ There is now a test pinning the alias, because the original defect was that
196
+ nothing asserted it existed.
197
+
198
+ ### Fixed
199
+
200
+ - **Protocol placeholders are docstrings, not bare `...`.** Nine
201
+ `py/ineffectual-statement` alerts across `src/cds/ml/model_selection.py`,
202
+ `src/cds/ml/voting.py` and `src/cds/tools/adapters.py` were the conventional
203
+ `...` terminating a `typing.Protocol` method. These are false positives in the
204
+ strict sense: `...` is the documented placeholder for a structurally-typed
205
+ method whose implementation lives in the real backend module, and no code path
206
+ executes it. `SoftVotingModel` is the only `@runtime_checkable` one, and
207
+ `isinstance` against a runtime protocol inspects attribute *presence* without
208
+ calling the body.
209
+
210
+ They became docstrings rather than `pass` because coverage.py excludes an
211
+ ellipsis-only body but counts `pass`; measured, swapping it in drops those
212
+ lines from 100% to 75% and breaks the coverage gate. `raise NotImplementedError`
213
+ has the same coverage problem and would additionally change behaviour if the
214
+ body were ever reached. `src/cds` already contained nine docstring-only bodies
215
+ with no alert on any of them.
216
+
217
+ - **`src/cds/tools/registry.py` imports `importlib` one way.** Three spellings
218
+ were mixed: `import importlib`, `import importlib.util` and
219
+ `from importlib import metadata`. The first was fully subsumed by the second.
220
+ Now `import importlib.metadata` and `import importlib.util`, with call sites
221
+ fully qualified. Four monkeypatch targets in `tests/` were retargeted to match.
222
+
223
+ - **Four `py/unnecessary-lambda` alerts in the test suite.** `lambda x: max(x)`
224
+ and `lambda values: sum(values)` are plain wrappers around a callable; the
225
+ callables are now passed directly.
226
+
227
+ - **`tests/test_fitting_bootstrap.py` imports `cds.modeling.fitting` one way.**
228
+ A module-level `from ... import` coexisted with function-local
229
+ `import ... as fitting`. The single `import ... as fitting` form is used now and
230
+ the module-level names are qualified through it.
231
+
232
+ ### Added
233
+
234
+ - **`tests/test_protocol_placeholders.py`** pins the protocol bodies on the AST,
235
+ because a docstring-only body and a docstring followed by `pass` compile to
236
+ almost identical instructions and only the syntax tree tells them apart. It also
237
+ asserts the placeholder semantics (`None` when called unbound), that
238
+ `SoftVotingModel` is still a working structural contract, and that every
239
+ declared signature and annotation still resolves. Negative-controlled against
240
+ four mutations, all caught: docstring-plus-`pass`, `...` reinstated, body
241
+ replaced by a real statement, and a statement appended after the docstring.
242
+
243
+ ### Changed
244
+
245
+ - README's pasted `cds --version` transcript now reads `System version 2.2.2`.
246
+ Every provenance and attestation statement in `README.md` and `SECURITY.md`
247
+ still refers to **2.2.1** deliberately: those describe the published release,
248
+ including its digests, and remain true until a newer one ships.
249
+
250
+
251
+ ### Fixed
252
+
253
+ - **Provenance claims are now scoped, measured, and guarded.** A follow-up report
254
+ asserted that PyPI had no PEP 740 attestation either. Re-measured directly, that
255
+ is **not** the case, so the previous text was left standing and made precise
256
+ rather than weakened:
257
+
258
+ - PyPI **2.2.1** serves a PEP 740 provenance bundle for **both** the wheel and
259
+ the sdist (HTTP 200 on the per-file `/integrity/.../provenance` endpoint),
260
+ and each bundle's `subject` digest equals the `sha256` PyPI publishes for
261
+ that file. The 404 in the report came from requesting
262
+ `https://pypi.org/integrity/scientific-computing-system/2.2.1/`, which is a
263
+ directory, not the per-file endpoint.
264
+ - npm **2.2.1** has **no** attestation: the attestations endpoint returns 404.
265
+ This part of the report was correct.
266
+
267
+ The security posture is therefore unchanged and more precisely stated. What
268
+ changed: `SECURITY.md` now separates the three things that were being conflated
269
+ — a **PEP 740 attestation** (Sigstore-signed, attests *who built this*),
270
+ **npm `dist.signatures`** (registry transport signing, attests nothing about
271
+ the build), and a **content digest** (`sha256` on PyPI, `dist.integrity` on
272
+ npm; pins *which bytes*, not *where they came from*). It lists the published
273
+ digests to pin, gives the commands that verify them, and states the exact
274
+ trusted-publisher coordinates still to be registered for npm.
275
+
276
+ - **Reproducible-build claim scoped to what was actually measured.** Two
277
+ consecutive builds of the same commit with the same pinned backend produced
278
+ byte-identical wheel and sdist. Those digests do **not** match the published
279
+ ones (the release runs a hash-locked Linux toolchain; the check ran elsewhere),
280
+ so the documentation now claims determinism for a fixed toolchain and
281
+ explicitly declines to claim the published artifacts are bit-for-bit
282
+ reproducible from source.
283
+
284
+ - **npm launcher prerequisite re-verified.** With `cds` absent from `PATH`, the
285
+ shim proceeds straight to interpreter resolution (`python`/`python3`/`py`) and
286
+ runs `python -m cds`; it never looks for a `cds` console script. README,
287
+ `SECURITY.md` and the docs already agreed on this wording, and it is now
288
+ backed by an explicit check rather than by reading the source.
289
+
290
+ ### Added
291
+
292
+ - `docs/checks/verify_provenance_claims.py` — a guard that parses the attestation
293
+ claims out of `README.md` and `SECURITY.md` and compares them against the live
294
+ registries, failing if the prose asserts something the registries contradict.
295
+ It also rejects prose that overstates `dist.integrity` as provenance or allows
296
+ the attested subject to differ from the published digest. Negative-controlled:
297
+ three false claims (PyPI not attested, npm attested, digest mismatch acceptable)
298
+ each turn it red. Wiring it into CI is left to the workflow owner; this change
299
+ is docs-only by scope.
300
+
301
+ ## [v2.2.1] - 2026-10-04
302
+
303
+ Documentation and release-surface corrections. **No library behaviour change**:
304
+ nothing under `src/cds/` was modified except the `__version__` constant, so no
305
+ numerical kernel, public API signature or CLI subcommand differs from 2.2.0.
306
+
307
+ The reason this patch release exists: `README.md` is the `long_description`, and
308
+ PyPI only re-reads it when a new release is uploaded. 2.2.0 shipped the README as
309
+ it stood before the truthfulness work below, so the PyPI project page for 2.2.0
310
+ still advertises claims the repository has since retracted. Publishing 2.2.1 is
311
+ what makes the corrected README the one PyPI renders.
312
+
313
+ ### Fixed
314
+
315
+ - **README performance claim corrected to the committed artifact.** The "catch"
316
+ paragraph asserted "~0.05 s versus ~0.0001 s ... roughly 580x slower" and
317
+ described it as "this machine's benchmark run", while pointing readers at
318
+ `docs/benchmarks.md` for "the hardware they came from". `benchmarks/results.json`
319
+ actually records 0.0696 s versus 0.000060 s (**1154.8x**) at commit `7213425`,
320
+ and that same file records Platform / CPU / Python / NumPy as "not recorded"
321
+ with an explicit "treat the absolute timings as unverified" warning. The line
322
+ added by the earlier truthfulness commit therefore contradicted the warnings it
323
+ shipped alongside. Both the README and `docs/why-pure-python.md` now quote the
324
+ artifact's own numbers and state that the environment was not recorded.
325
+
326
+ - **npm launcher prerequisite stated correctly.** README and `SECURITY.md` said
327
+ the `scs` shim works once `cds` is "on your PATH". `index.js` resolves an
328
+ interpreter (`python`/`python3`/`py`) and runs `python -m cds`; it never looks
329
+ for a console script on `PATH`. Corrected to "requires the Python distribution
330
+ installed so that `python -m cds` resolves".
331
+
332
+ - **Stale version references left behind by the 2.2.1 bump.** The README's pasted
333
+ `cds --version` transcript still read `System version 2.2.0` after the version
334
+ moved, and `SECURITY.md` still recommended pinning `==2.2.0`. Since the README
335
+ is the `long_description`, that line would have shipped verbatim to the PyPI
336
+ project page. Both were re-derived from live commands at 2.2.1.
337
+
338
+ Every other pasted transcript was re-checked against the installed 2.2.1 wheel
339
+ and found current: the quickstart output (SVD singular values, damped-oscillator
340
+ final state, regression fit), `cds modules` printing 26 rows and omitting exactly
341
+ the nine documented modules, the structural claims (34 subpackages, 35 public
342
+ feature modules, 505 names / 342 functions / 163 classes), the benchmark ratio
343
+ against `benchmarks/results.json`, and all five documented extras.
344
+
345
+ Two further `SECURITY.md` claims were false and are corrected: `scs` was
346
+ documented as needing a `cds` console script on `PATH` when the launcher
347
+ resolves an interpreter and runs `python -m cds` (verified: the shim prints
348
+ `System version 2.2.1` with no `cds` on `PATH`), and the PyPI attestation cell
349
+ claimed a PEP 740 bundle for the published 2.2.0 when PyPI serves none.
350
+
351
+ The pin example is now version-agnostic by construction, so it cannot rot at
352
+ the next bump.
353
+
354
+ - **Module-surface claims are now accurate.** "34 subpackages" silently omitted
355
+ the two top-level public modules (`causal.py`, `sensitivity.py`), and
356
+ "`cds modules` for the live list" was wrong twice over: that command prints a
357
+ curated 26-entry subset and omits `bayes`, `causal`, `core`, `fractals`,
358
+ `genetics`, `infotheory`, `interpolate`, `pde`, and `wavelets`. README,
359
+ `docs/api.md` and `docs/index.md` now state the real counts and flag
360
+ `cds modules` as a subset. The unsupported "46 public functions / 534 exports"
361
+ hero claim does not exist in the repository or in any reachable commit; the
362
+ README instead carries counts derived from the package itself (505 exports:
363
+ 342 functions, 163 classes across 35 feature modules).
364
+
365
+ - **Documentation no longer claims npm is unpublished.** npm 2.2.0 is live and
366
+ npm is a supported channel, but `README.md` line 41 still said "npm is no
367
+ longer published". Because `README.md` is listed in the npm `files` allowlist,
368
+ that sentence shipped **verbatim inside the published 2.2.0 tarball**, so the
369
+ npm package page contradicted its own README. `README.md`, `SECURITY.md` and
370
+ `docs/related.md` now describe both channels accurately; the npm version badge
371
+ is restored now that the registry and PyPI agree.
372
+
373
+ - **A successful publish is no longer reported as a failure while npm is still
374
+ propagating it.** `npm publish` returns as soon as the registry accepts the
375
+ upload, but the version becomes readable on the read path asynchronously. The
376
+ post-publish check read once, immediately, and on run `37136131220` got
377
+ `npm error 404 No match found for version 2.2.0` — while 2.2.0 was in fact
378
+ published and recorded by the registry ninety seconds later. A maintainer
379
+ reading that run had every reason to believe the release had broken. Three
380
+ sibling repositories hit the same false failure.
381
+
382
+ The check now polls the registry with backoff over a budget of several minutes,
383
+ succeeds on the first match, and still fails closed if the version genuinely
384
+ never appears, emitting a `::warning::` first so a slow-but-successful publish
385
+ is never read as a hard failure.
386
+
387
+ It queries the registry's JSON API instead of `npm view`, which was a poor fit:
388
+ it reports "absent" and "denied" with the same `E404`, and it resolves against
389
+ the userconfig the job created for *writing*, so a read-only confirmation had no
390
+ reason to touch publish credentials at all. Both directions are exercised
391
+ against a stub registry, and the retry budget itself is asserted, since
392
+ shortening it to make a test fast is what caused the bug.
393
+
394
+ - **The publish path is now guarded rather than merely enabled.** The launcher
395
+ contract test previously asserted that publishing stayed disabled, which would
396
+ have silently passed against a disabled workflow. It now asserts a real
397
+ `npm publish --provenance` invocation, `id-token: write`, the absence of
398
+ `private: true`, the absence of the disabled stub, and the presence of every
399
+ gate that makes a publish safe: the registry version-existence check, the
400
+ `npm pack --dry-run` tarball allowlist, and the npm/Python version lockstep.
401
+
402
+ - **The npm toolchain version floor rejected a compliant toolchain.** The first
403
+ real publish run failed on this gate:
404
+
405
+ ```
406
+ npm --version | grep -Eq '^11\.(5[1-9]|[6-9][0-9])\.|^1[2-9]\.'
407
+ ::error::npm 11.5.1+ is required for OIDC trusted publishing
408
+ ```
409
+
410
+ On Node 24, setup-node installs npm **11.19.0**. The `[6-9][0-9]` alternative
411
+ covers minors 60-99, so `19` never matched and the gate failed on a toolchain
412
+ that meets the floor. A regex cannot express "greater than or equal to" for a
413
+ dotted version without enumerating every minor, which is exactly the mistake
414
+ that shipped. The gate now parses the version, strips any leading `v` and
415
+ prerelease suffix, and compares major/minor/patch as integers against 11.5.1.
416
+ The Node half of the same gate ignored the patch component: it compared only
417
+ major and minor, so `22.9.0` was accepted even though the documented floor is
418
+ 22.14.0. Both halves now use the same integer comparison.
419
+
420
+ - **Token-mode npm publish failed with `ENEEDAUTH` while holding a valid
421
+ secret.** The run reached `npm publish` with `NODE_AUTH_TOKEN` populated and
422
+ still got:
423
+
424
+ ```
425
+ npm error code ENEEDAUTH
426
+ npm error need auth This command requires you to be logged in to
427
+ https://registry.npmjs.org/
428
+ ```
429
+
430
+ Root cause: `actions/setup-node` was configured without `registry-url`, so it
431
+ wrote no npm userconfig at all. `NODE_AUTH_TOKEN` on its own is inert — npm only
432
+ substitutes it into a credential when some userconfig maps
433
+ `//registry.npmjs.org/` to `${NODE_AUTH_TOKEN}`. With no such entry npm never
434
+ attempts authentication, which is why the failure was `ENEEDAUTH` (no
435
+ authentication attempted) rather than `E401` (attempted and rejected) even
436
+ though the secret was present and correct. The fix is
437
+ `registry-url: "https://registry.npmjs.org"` on `setup-node`.
438
+
439
+ Separately, the credential check lived inline inside the publish step, so its
440
+ failure text appeared in the log while `npm publish` was invoked anyway. It is
441
+ now its own step ahead of both publish steps, so a non-zero exit ends the job
442
+ before npm can run, and it covers the OIDC mode too (verifying the runner
443
+ actually granted `id-token: write`, which the previous version never checked).
444
+
445
+ - **The `bin` map is now pinned by tests, so a broken launcher command cannot
446
+ ship silently.** The `npm warn publish "bin[scs]" script name bin/scs.js was
447
+ invalid and removed` message had been reported as a defect that would leave
448
+ the published package with no working `scs` command. **That report was wrong.**
449
+ npm normalises the redundant `./` prefix and ships the entry either way; the
450
+ packed tarball keeps `bin: { scs: "./bin/scs.js" }` alongside `bin/scs.js`, and
451
+ installing it creates `scs`, `scs.cmd` and `scs.ps1` and `scs --version`
452
+ succeeds. `axiomize@1.12.4`, published from the identical shape, ships the same
453
+ and is not deprecated. No `package.json` change is required.
454
+
455
+ What *is* a real hazard is the opposite: npm ships a `bin` pointing at a
456
+ missing file, or one excluded by `files`, with **no warning at all**. Five
457
+ tests now assert the bin map is a valid command-name to path mapping, that
458
+ every target exists and is covered by `files`, that the shim carries a `node`
459
+ shebang, and that the real tarball (`npm pack --dry-run --json`) still contains
460
+ both the shim and the bin entry. One further test documents that the `./`
461
+ prefix is intentional so the cosmetic warning is not "fixed" by a future
462
+ maintainer.
463
+
464
+ ### Added
465
+
466
+ - **`tests/test_readme_surface.py`** derives the README's structural claims from
467
+ `src/cds/` and from the installed package: subpackage count, presence of both
468
+ top-level public modules, the export total, per-module table coverage, the
469
+ benchmark ratio against `benchmarks/results.json`, and a guard against
470
+ describing `cds modules` as exhaustive. This drift was previously invisible to
471
+ CI, which is how it survived several releases. Verified by mutation: five
472
+ separate re-introductions of the audited defects each turn the suite red.
473
+
474
+ - **`codemeta.json` is now a locked version surface.** It was left out of the
475
+ original five surfaces and drifted: it still declared `2.1.0` after the package
476
+ reached 2.2.0, while every other surface had moved. CodeMeta is a
477
+ machine-readable publication record, so a stale `version` there advertises the
478
+ previous release to every automated consumer while the installed package
479
+ reports a different one. `scripts/check_version_lockstep.py` now reads it and
480
+ `tests/test_codemeta_version_lockstep.py` fails CI on drift. It is also added
481
+ to the sdist allowlist, without which that suite failed with `FileNotFoundError`
482
+ when run from an unpacked sdist.
483
+
484
+ - README coverage: `cds.core` and `cds.graph` rows, `examples/` (35 runnable
485
+ files) and `dashboard/app.py` entries, all 13 CLI subcommands, the `[pandas]`
486
+ extra, `paper.md`/`paper.bib` (JOSS) and `codemeta.json`, and a Contributing
487
+ section with the `pip install -e ".[dev]"` / `pytest` / `mkdocs serve` loop and
488
+ the 100% blended-coverage gate. Duplicated prose was removed (the supply-chain
489
+ section now defers to `SECURITY.md` instead of restating it, and the generic
490
+ "Common use cases" filler is gone).
491
+
492
+ - **Two supported npm publish modes**, selected by the `use_token_fallback`
493
+ dispatch input (boolean, default `false`):
494
+ - **OIDC trusted publishing** (preferred, default) — `id-token: write`,
495
+ `npm publish --provenance`. No registry secret involved.
496
+ - **Token mode** (`use_token_fallback=true`) — uses the repository's existing
497
+ `NPM_TOKEN` secret via `NODE_AUTH_TOKEN`. This is the mode in use while the
498
+ npmjs.com trusted-publisher registration is pending.
499
+
500
+ The token mode deliberately omits `--provenance`. Provenance is an OIDC-only
501
+ Sigstore attestation: a token cannot mint one, and npm rejects the
502
+ combination. The token mode prints a NOTICE that the release carries no
503
+ provenance rather than passing a flag that cannot work or implying an
504
+ attestation exists. Both modes are fail-closed: a requested mode with no usable
505
+ credential exits non-zero with an actionable message, and token mode never runs
506
+ automatically, so a broken OIDC configuration cannot silently downgrade to the
507
+ long-lived credential.
508
+
509
+ ### Changed
510
+
511
+ - **npm publishing is real again.** This reverses two earlier decisions, both
512
+ deliberate at the time and recorded here so the history is not silently erased:
513
+ the decision in `52717c5` to disable npm publishing (which replaced the publish
514
+ step with `run: echo "npm publishing is disabled; PyPI is the install path" &&
515
+ exit 0`), and `"private": true` in `package.json`, added by `#140` while
516
+ publishing was disabled. `private: true` makes `npm publish` refuse to run at
517
+ all, so the flag had to go before the workflow could work. The `files` allowlist
518
+ is retained: it is what keeps the repository (tests, CI workflows, 10k+
519
+ statements of Python, promo media) out of the published tarball. The npm
520
+ channel is on OIDC trusted publishing (`id-token: write`,
521
+ `npm publish --provenance`); no long-lived registry token is used on the
522
+ primary path.
523
+
524
+ - README shortened with **higher** coverage: the supply-chain section dropped from
525
+ 209 lines to a 3-line summary plus a link, and "The catch" reduced to a short
526
+ paragraph.
527
+
528
+ - **This release carries a PyPI attestation; 2.2.0 does not.** PyPI's JSON API
529
+ reports zero PEP 740 attestation bundles for 2.2.0, which went out in token
530
+ mode — a token cannot mint a Sigstore attestation. 2.2.1 is published by
531
+ `release.yml` through `pypa/gh-action-pypi-publish` with Trusted Publishing
532
+ (OIDC), so it will carry one, as long as the `pypi` environment's trusted
533
+ publisher is configured — a misconfiguration fails the publish loudly rather
534
+ than degrading silently.
535
+
536
+ ## [v2.2.0]
537
+
538
+ Security hardening of the provenance path surface: provenance manifest paths
539
+ are confined (`src/cds/_paths.py`), and the runtime dependency graph is guarded.
540
+ No numerical kernel or public API signature changed. (Content owned by the
541
+ security agent; this heading exists to satisfy the version-lockstep gate.)
542
+
543
+ ## [v2.1.0] - 2026-09-30
544
+
545
+ Release-hardening pass covering the CI, quality-gate and packaging surface. No
546
+ numerical kernel, public API signature or `cds` CLI subcommand changed.
547
+
548
+ New public modules that first shipped in this release line (noted here because
549
+ the release notes below cover only the hardening pass): `cds.validation`
550
+ (cross-method verification, distribution-shift reporting), `cds.causal`
551
+ (assumption-gated estimators — no causal-structure inference from observational
552
+ correlation), `cds.sensitivity` (local and variance-based global sensitivity,
553
+ identifiability), `cds.units` (SI dimensional analysis), `cds.workflow`
554
+ (approval-gated, fail-closed orchestration), `cds.provenance` (manifests,
555
+ hashing, checkpoints), `cds.data_io` (streaming I/O, optional HDF5/NetCDF),
556
+ `cds.tools` (lazy optional-backend adapters), and `cds.uncertainty` (analytic
557
+ and correlated Monte-Carlo propagation).
558
+
559
+ ### Fixed
560
+
561
+ - **npm launcher (`index.js`, `bin/scs.js`)**: the published launcher could not be
562
+ parsed by Node (`SyntaxError: Unexpected token ';'`), and had it parsed it
563
+ spawned `python -m scs.cli`, a module that has never existed in any release
564
+ (the import name is `cds`). Both defects shipped in `1.0.0` on npm and were
565
+ invisible because `npm test` was a placeholder that exited 1 without running
566
+ anything. The launcher is now syntactically valid, targets `python -m cds`,
567
+ propagates the child's exit status, and reports one actionable message when no
568
+ interpreter is found.
569
+ - **npm package contents**: `package.json` shipped no `files` allowlist, so a
570
+ publish would have uploaded the whole repository (tests, workflows, 10k+
571
+ statements of Python, promo media). Publication is now restricted to an
572
+ explicit allowlist.
573
+ - **npm version drift**: `package.json` declared `1.0.0` while the Python
574
+ distribution was at `2.1.0`. It now tracks the Python version and CI fails on
575
+ any drift.
576
+ - **Version-discipline bypass under rebase merges**
577
+ (`scripts/check_version_discipline.py --base-ref HEAD^1`): `HEAD^1` resolves to
578
+ the previous commit of the *same branch*, so in a multi-commit rebase merge only
579
+ the final commit's diff was inspected. A PR could change `src/cds/` in one
580
+ commit, follow with an unrelated commit, and pass the gate with no version bump
581
+ at all. The gate now diffs against the PR merge-base.
582
+ - **Release fail-closed behaviour**: the publish job could report success after a
583
+ verification step had failed. That path is closed; every verification failure
584
+ now fails the job before any registry or tag mutation.
585
+ - **Docs deployment ordering**: `deploy-docs` depended only on the `test` matrix,
586
+ so gh-pages could be updated from a run whose `audit`, `version_discipline` or
587
+ `test`-aggregate gates had failed. It now depends on the aggregate `CI` job.
588
+ - **sdist test-suite failure**: `tests/test_release_contract.py` reads
589
+ `.github/workflows/*.yml`, which the sdist `only-include` list omitted, so the
590
+ shipped source distribution could not pass its own test suite (13 failures).
591
+ The CI workflow files are now part of the sdist.
592
+
593
+ ### Added
594
+
595
+ - **`npm test` contract suite** (`npm.test.js`): assertions covering
596
+ `node --check` parseability, the `cds` module target, argument forwarding, exit
597
+ status propagation, the `files` allowlist, npm/Python version agreement, and a
598
+ guard that `npm-publish.yml` stays a disabled no-op. CI runs `npm run check`
599
+ and `npm test` on every push and pull request; **nothing in CI publishes to
600
+ a registry**.
601
+ - **`scripts/check_version_lockstep.py`**: machine-enforced agreement across
602
+ `pyproject.toml`, `package.json`, `src/cds/_version.py`, `CITATION.cff`, the
603
+ runtime `cds.__version__` import, `CHANGELOG.md` and -- with `--dist-dir` --
604
+ the built wheel and sdist metadata. `2.1.0` had shipped to PyPI with no
605
+ `CHANGELOG.md` entry; that class of drift is now a red build.
606
+ - **Wheel/sdist content assertions in CI**: the packaging job now asserts the
607
+ exact filename, distribution name, version, `py.typed` marker, sdist root
608
+ directory and the absence of forbidden paths (test fixtures, promo media,
609
+ `.github`, `site/`) rather than building artifacts and trusting them.
610
+ - **Timeouts on every CI job** and per-job least-privilege `permissions:`.
611
+
612
+ ### Changed
613
+
614
+ - All GitHub Actions references are pinned to full immutable commit SHAs;
615
+ previously several workflows used mutable `@v4` / `@v7` / `@v8` tags.
616
+ - Branch ruleset for `main` extended in place (not replaced) to require the
617
+ aggregate `CI` check plus the `Installed CLI Smoke`, version-discipline,
618
+ packaging and npm contract jobs, and to dismiss stale reviews on push.
619
+ - npm publishing stays disabled per product decision ("npm is no longer
620
+ published"; `npm-publish.yml` is a deliberate no-op). `package.json` is marked
621
+ `private`, the npm contract test asserts the workflow stays a no-op, and
622
+ nothing in CI uploads to a registry.
623
+ - Removed the dead workflow files that main did not already remove:
624
+ `wsl-science-runner-smoke.yml` (targeted a self-hosted runner label with zero
625
+ registered runners). The retired `public-external-validation-p08-*` experiment
626
+ workflows and the one-shot `p08-cancel-noncanonical-runs.yml` /
627
+ `tmp-compassion-raw-acquire.yml` jobs were deleted on `main` directly and are
628
+ kept deleted here.
629
+
630
+ ## [v2.0.1] - 2026-09-29
631
+
632
+ Metadata-only patch release for improved PyPI discoverability. No runtime API or numerical behavior changes.
633
+
634
+ ### Changed
635
+
636
+ - Expanded PyPI keywords and classifiers for reproducibility, uncertainty quantification, sensitivity analysis, dimensional analysis, scientific workflows, ODE/PDE, and related scientific-computing searches.
637
+ - Refreshed development lock versions required by the current security audit.
638
+ - Normalized repository trailing whitespace required by pre-commit.
639
+
640
+
641
+ ### Added
642
+
643
+ - **Random Forest classifier** (`cds.ml`): bagged CART trees with
644
+ bootstrap resampling and per-split feature randomization (`sqrt`/`log2`
645
+ / explicit count), fully deterministic under a seed.
646
+ - **Metrics** (`cds.ml`): `accuracy`, `confusion_matrix`,
647
+ `precision_recall_f1`, `macro_prf`, regression `mse`/`mae`/`r2_score`,
648
+ and tie-aware rank-based `roc_auc`.
649
+ - **Cross-validation** (`cds.ml.model_selection`): `k_fold_indices` and
650
+ `cross_val_score` over the shared estimator interface.
651
+ - **Interpolation module** (`cds.interpolate`): `interp1d` (linear /
652
+ nearest) and `interp2d` (bilinear on regular grids).
653
+ - **SVD** (`cds.math_utils`): one-sided Jacobi decomposition with
654
+ `svd`, `rank` and `condition_number`; full U/Vt factors.
655
+ - **STFT / spectrogram** (`cds.signals`): Hann/Hamming windows, framed
656
+ zero-padded transforms reusing the radix-2 FFT, `STFTResult`.
657
+ - **Gradient Boosting classifier** (`cds.ml`): logistic-loss boosted
658
+ regression trees with Newton leaf values; binary labels.
659
+ - **Bootstrap confidence intervals** (`cds.stats`): percentile-method
660
+ `bootstrap_ci` and two-sample `bootstrap_diff_ci`.
661
+ - **Metropolis-Hastings sampler** (`cds.montecarlo`): 1-D random-walk
662
+ MCMC with burn-in/thinning and acceptance-rate reporting.
663
+ - **Symplectic integrators** (`cds.diffeq`): semi-implicit Euler and
664
+ velocity Verlet with forward/backward integration.
665
+ - **Constrained optimization** (`cds.optimization`): projected gradient
666
+ descent for box bounds and quadratic-penalty constrained solves.
667
+ - **Hypergeometric & negative-binomial distributions**
668
+ (`cds.probability`), pmf + cdf for both.
669
+ - **TF-IDF ranked retrieval** (`cds.knowledge`): `rank_tfidf` across
670
+ concepts and notes with smoothed idf.
671
+ - **Haar wavelet transform** (`cds.signals`): `dwt` / `idwt` /
672
+ `dwt_multi_level`, orthonormal with perfect reconstruction.
673
+ - **PDE solvers** (`cds.pde`): explicit FTCS heat equation (Dirichlet /
674
+ Neumann, stability-guarded) and wave equation (CFL-guarded).
675
+ - **Gaussian Naive Bayes** (`cds.ml`): log-space scoring with variance
676
+ smoothing.
677
+ - **Correlation-mining engine** (`cds.hypothesis`): `mine_correlations`
678
+ turns numeric datasets into statistically tested, falsifiable
679
+ `Hypothesis` objects.
680
+ - **Power analysis** (`cds.stats`): `power_t_test`,
681
+ `power_proportion_test` and `required_n_per_group` sample-size solver.
682
+ - **VotingClassifier** (`cds.ml`): hard (majority vote) and soft
683
+ (averaged probabilities) ensembles over the shared estimator interface.
684
+ - Four new runnable demos under `examples/`: interpolation, PDE,
685
+ ensemble showcase and the end-to-end discovery pipeline.
686
+ - **PCA end-to-end demo** (`examples/pca_demo.py`): scaling vs raw
687
+ variance comparison, component selection, 2-D ASCII projection,
688
+ reconstruction error and train/test discipline, with a matching
689
+ tutorial (`docs/tutorials/pca_demo.md`).
690
+ - **ML correctness reference table** (`scripts/verify_ml_reference.py`,
691
+ `docs/ml_reference.md`), LogisticRegression, DecisionTree, KMeans,
692
+ PCA and LinearRegression checked against scikit-learn 1.9.0 outputs
693
+ on a fixed seeded dataset; one-command, dependency-free verification.
694
+
695
+ ### Changed
696
+
697
+ - `DecisionTreeClassifier` now accepts `max_features` and `seed` for
698
+ random-forest-style split randomization (default behavior unchanged).
699
+ - The README now displays the sklearn-parity badge and links the ML
700
+ Reference table. (The matching `ml-reference` CI job is prepared but
701
+ not yet applied. It needs a push from a token with the `workflow`
702
+ OAuth scope; see the `backup/pre-reorder` branch.)
703
+
704
+ ## [v2.0.0] - 2026-09-05
705
+
706
+ Scientific workflow platform release. Reorganises the project from a numerical
707
+ methods library into a layered system that separates computation, analysis,
708
+ scientific assurance, orchestration, and data handling.
709
+
710
+ ### Added
711
+
712
+ - Uncertainty propagation, provenance capture, and tool discovery.
713
+ - Dimensional analysis, domain checks, and scalable data I/O.
714
+ - Scientific adapters, sensitivity analysis, and tool orchestration.
715
+ - CLI catalog refreshed for the expanded module set.
716
+
717
+ ### Changed
718
+
719
+ - The project is organised into explicit layers (compute / analysis /
720
+ assurance / orchestration / data) with dependencies pointing downward.
721
+ - Release pipeline enforces a single publish authority.
722
+
723
+ ## [v1.6.2] - 2026-08-23
724
+
725
+ Patch release carrying the PyPI deprecation tombstone for the former
726
+ `cognitive-discovery-system` distribution name, pointing users at
727
+ `scientific-computing-system`. No API change; the import name stayed `cds`.
728
+
729
+ ## [v1.6.1] - 2026-08-21
730
+
731
+ A **patch** release completing the JSON round trip for core data models.
732
+
733
+ ### Added
734
+
735
+ - **`cds.core`**: `Hypothesis.from_dict()`: the inverse of `to_dict()`.
736
+ CLI/JSON output can now be re-imported: enum strings are coerced back to
737
+ `Domain` / `HypothesisStatus`, ISO-8601 timestamps are parsed, and missing
738
+ optional keys fall back to constructor defaults. Invalid `status` values
739
+ raise `ValueError`.
740
+
741
+ ### Changed
742
+
743
+ - Internal layering cleanup: shared special-function kernels moved to their
744
+ single home (`cds.math_utils.special`) so lower-level packages never depend
745
+ on higher-level ones; a suite-level import-direction guard enforces this.
746
+ - `cds.cli` is now a package (`_style` / `_handlers` / `_parser`) with
747
+ identical behaviour; refreshed module descriptions in `cds modules`.
748
+
749
+ ## [v1.6.0] - 2026-08-21
750
+
751
+ A **minor** release deepening the ML, probability, ODE, and optimization
752
+ toolkits toward scikit-learn / SciPy teaching parity, still zero runtime
753
+ dependencies, still 100% blended coverage.
754
+
755
+ ### Added
756
+
757
+ - **`cds.ml`**: `KNeighborsClassifier` / `KNeighborsRegressor` (brute-force,
758
+ deterministic tie-breaking), `KMeans` (k-means++ seeding, seeded),
759
+ `DecisionTreeClassifier` (CART + Gini), `LogisticRegression` (stable-BCE
760
+ gradient descent, optional L2), `LinearRegression` (closed-form vector OLS
761
+ via normal equations), `PCA` (cyclic Jacobi eigen-solver, transform /
762
+ inverse_transform), `StandardScaler`, `train_test_split` (seeded)
763
+ - **`cds.probability`**: chi-square and Student-t distributions
764
+ (`chi2_pdf/cdf/ppf`, `t_pdf/cdf/ppf`), `gamma_pdf` + `sample_gamma`
765
+ (Marsaglia–Tsang with shape<1 boost), `beta_pdf` + `sample_beta`
766
+ (exact gamma-ratio identity)
767
+ - **`cds.diffeq`**: implicit stiff solvers: `backward_euler`,
768
+ `trapezoid_method` (Crank–Nicolson) and their `_system` variants; unified
769
+ θ-method core with Newton iteration over analytic or central-difference
770
+ Jacobians via the shared PLU solver
771
+ - **`cds.optimization`**: `nelder_mead` simplex (degenerate-simplex and
772
+ symmetric false-convergence guards), `simulated_annealing` (Metropolis rule,
773
+ box bounds, seeded)
774
+ - **`cds.stats`**: nonparametric tests: `mann_whitney_u` and
775
+ `wilcoxon_signed_rank` with tie/zero corrections (normal approximation)
776
+
777
+ ### Fixed
778
+
779
+ - Test-suite pyplot figures are now closed per test, silencing matplotlib's
780
+ "more than 20 figures" memory warning in long sessions
781
+
782
+ ### Changed
783
+
784
+ - README "Why CDS?" pitch strengthened with proof numbers and a cross-domain
785
+ snippet; stale counts/versions synced across metadata (19 modules)
786
+
787
+ ## [v1.5.0] - 2026-07-20
788
+
789
+ A **minor** release expanding algorithms across graph theory, Monte Carlo,
790
+ linear algebra, and CLI, still zero runtime dependencies.
791
+
792
+ ### Added
793
+
794
+ - **`cds.graph`**: `degree`, `connected_components`, `bellman_ford`,
795
+ `floyd_warshall`, `prim_mst`
796
+ - **`cds.montecarlo`**: `mc_expectation`, `hit_or_miss` (2-D area estimation)
797
+ - **`cds.math_utils`**: `vector_norm`, `frobenius_norm`, `matrix_trace`
798
+ - **CLI**: `cds integrate <sin|cos|exp|x2|unit> --a --b -n --method`
799
+
800
+ ## [v1.4.0] - 2026-07-20
801
+
802
+ A **minor** release expanding core scientific APIs and CLI ergonomics.
803
+ Zero runtime dependencies preserved.
804
+
805
+ ### Added
806
+
807
+ - **`cds.probability`**: CDFs (`gaussian_cdf`, `uniform_cdf`, `exponential_cdf`),
808
+ `geometric_pmf`, samplers (`gaussian_sample` Box–Muller, `exponential_sample`,
809
+ `poisson_sample` Knuth)
810
+ - **`cds.stats`**: `spearman_correlation` (midranks), `percentile`, `z_scores`
811
+ - **`cds.scientific`**: constants `epsilon_0`, `g`, `mu_0`; formulas
812
+ `coulomb_force`, `centripetal_acceleration`, `pendulum_period`, `doppler_frequency`
813
+ - **CLI**: `cds stats <nums>`, `cds sample <dist> -n N --seed …`
814
+
815
+ ### Changed
816
+
817
+ - `cds info` no longer hardcodes a stale test count; module list includes modeling/knowledge/nlp
818
+
819
+ ## [v1.3.2] - 2026-07-20
820
+
821
+ A **patch** release expanding the optional ``cds[plot]`` surface.
822
+
823
+ ### Added
824
+
825
+ - **`cds.plot` charts**: `plot_multi_series`, `plot_scatter`, `plot_regression`
826
+ (OLS via `cds.stats`), `plot_power_spectrum` (via `cds.signals`),
827
+ `plot_seasonal_decompose` (4-panel), `plot_heatmap`, `plot_loss`,
828
+ `save_figure(..., close=)` helper; histogram gains ``density=``
829
+ - **CLI**: `cds plot … --kind series|hist|acf --file out.png`
830
+
831
+ ### Changed
832
+
833
+ - Docs / Cookbook / demo updated for the expanded plot API
834
+
835
+ ## [v1.3.1] - 2026-07-20
836
+
837
+ A **patch** release. Fixes the console entry point so `cds` works after a
838
+ plain PyPI install.
839
+
840
+ ### Fixed
841
+
842
+ - **`[project.scripts]`**: entry point was `cds.cli:app` but the CLI exports
843
+ `main` (argparse). Installing from PyPI then raised
844
+ `ImportError: cannot import name 'app' from 'cds.cli'`. Now points to
845
+ `cds.cli:main`. `python -m cds` was already correct.
846
+
847
+ ## [v1.3.0] - 2026-07-20
848
+
849
+ A **minor** release focused on **visualization and ergonomics**. Adds the
850
+ optional ``cds[plot]`` matplotlib extra, a CLI PNG export path, a companion
851
+ notebook, and documentation. The zero-dependency core is unchanged: matplotlib
852
+ is only imported when a plot function runs (or when ``cds plot --file`` is
853
+ used).
854
+
855
+ ### Added
856
+
857
+ - **`cds.plot` optional package** (`src/cds/plot/`):
858
+ - `plot_series`, `plot_histogram`, `plot_waveform`, `plot_spectrum`
859
+ - `plot_acf` / PACF stems via `cds.stats` time-series helpers
860
+ - `plot_optimization_path` for 2-D optimizer trajectories
861
+ - Lazy matplotlib backend with install-hint `ImportError`
862
+ - **Extra**: `pip install scientific-computing-system[plot]` (also in `[all]`)
863
+ - **CLI**: `cds plot 1,2,3 --file out.png` saves a PNG when matplotlib is
864
+ installed; without `--file` the existing ASCII terminal plot remains
865
+ - **Examples**: `examples/plot_demo.py`, `examples/plotting_notebook.ipynb`
866
+ - **Docs**: Cookbook matplotlib section, API reference for `cds.plot`, README /
867
+ module tables, ROADMAP v1.3.0 track
868
+
869
+ ### Changed
870
+
871
+ - CI main matrix installs `.[pandas,plot]` so optional bridges stay at 100%
872
+ coverage; minimal-deps job omits `cds/plot/*` like `pandas_io`
873
+ - PyPI description mentions optional matplotlib plotting
874
+
875
+ ## [v1.2.3] - 2026-06-29
876
+
877
+ A **patch** release. Fixes the release pipeline that silently broke every
878
+ publish since v1.1.8.
879
+
880
+ ### Fixed
881
+
882
+ - **Release workflow (`release.yml`)**: removed an invalid
883
+ `administration: write` entry from the `sync-about` job's `permissions:`
884
+ block. `administration` is not a valid `permissions:` key, so GitHub
885
+ rejected the entire workflow file as a "workflow file issue" before any
886
+ job could start, failing in 0s and leaving v1.1.9 onward without a PyPI
887
+ upload or GitHub Release. The About-sync step is now best-effort
888
+ (`continue-on-error: true`) since `gh repo edit` needs an admin REST
889
+ scope the default `GITHUB_TOKEN` can't grant; the repo description is
890
+ synced by hand on release.
891
+
892
+ ## [v1.2.2] - 2026-06-29
893
+
894
+ A **patch** release. No code changes. Documentation-only refresh.
895
+
896
+ ### Changed
897
+
898
+ - **README: removed pictographic emoji** from the top navigation row, the
899
+ callout blocks, the "Support the project" section heading, and the trailing
900
+ sign-off. Em dashes are preserved. Brings the README in line with the
901
+ emoji-free house style already applied to the docs and live PR bodies.
902
+ - **`.gitignore`: ignore local promo-GIF QA scratch** (audit/compare/measure
903
+ scripts under `scripts/_*.py` and extracted frames under `assets/_qa_*/`),
904
+ which are one-off diagnostic tooling and were never meant to ship.
905
+
906
+ ## [v1.2.1] - 2026-06-28
907
+
908
+ A **patch** release. No code changes. Metadata-only refresh to improve
909
+ PyPI discoverability.
910
+
911
+ ### Changed
912
+
913
+ - **Strengthened PyPI `description`**: the short one-liner now names all 18
914
+ domain modules (quantum circuits, ML, NLP, signal processing, optimization,
915
+ statistics & time-series, ODE solvers, Monte Carlo, symbolic math, knowledge
916
+ graphs, hypothesis generation) and states the zero-runtime-dependency
917
+ guarantee. Improves search-result relevance on PyPI.
918
+ - **Expanded `keywords`** from 12 to 20 entries, aligning them with the GitHub
919
+ repository topics (added `machine-learning`, `nlp`, `numerical-integration`,
920
+ `knowledge-graph`, `symbolic-math`, `data-analysis`, `physics`,
921
+ `hypothesis-generation`, `numerical-methods`; dropped the redundant `fft`
922
+ in favour of the broader `signal-processing`).
923
+
924
+ ## [v1.2.0] - 2026-06-25
925
+
926
+ A **minor** release. The theme is **horizontal expansion + hardening**: three
927
+ new domain features (time-series analysis, signal-filter design, 2-D
928
+ quadrature), an optional pandas interop extra, and a documentation overhaul
929
+ (Cookbook, Architecture guide, expanded Tour). Plus numerical-stability fixes
930
+ and a no-behavior-change refactor of the two largest source files.
931
+
932
+ No existing public API is removed or renamed; the `cds[pandas]` adapter is
933
+ gated behind an optional extra so the zero-dependency core is untouched.
934
+
935
+ ### Added
936
+
937
+ - **`cds.stats`: time-series analysis** (`src/cds/stats/time_series.py`):
938
+ - `moving_average`, `exponential_smoothing`, `difference`, `seasonal_decompose`
939
+ - `autocorrelation_function` (sample ACF), `partial_autocorrelation_function` (PACF)
940
+ - `kpss_statistic` (stationarity test) and `ljung_box` (autocorrelation test),
941
+ both returning result objects with `.statistic` / `.p_value`
942
+ - Exported from the top-level `cds.stats` namespace.
943
+ - **`cds.signals`: filter design** (`src/cds/signals/filters.py`):
944
+ - `butter_lowpass(order, cutoff)`: Butterworth IIR low-pass coefficient design
945
+ - `apply_filter(signal, coeffs)`: direct-form IIR application
946
+ - `moving_median(signal, window)`: order-statistic denoiser (edge-preserving)
947
+ - **`cds.numerical_integration`: 2-D quadrature** (`src/cds/numerical_integration/`):
948
+ - `simpson_2d(f, ax, bx, ay, by, nx, ny)`: 2-D tensor-product Simpson rule
949
+ - `gaussian_quadrature_2d(f, ax, bx, ay, by, n)`: 2-D tensor-product Gauss-Legendre
950
+ - **`cds[pandas]` optional extra** (`src/cds/data_analysis/pandas_io.py`):
951
+ - `to_dataframe(data_set)` / `from_dataframe(df)` round-trip a `DataSet` to/from
952
+ a `pandas.DataFrame`, guarded so importing `cds` never requires pandas.
953
+ - Declared as an optional dependency in `pyproject.toml` (`pandas = {version = ...}`).
954
+ - **Documentation**:
955
+ - **`docs/cookbook.md`**: a new problem-oriented recipe book (~48 recipes, one
956
+ per concrete task), verified end-to-end against the real API by
957
+ `_verify_cookbook.py`.
958
+ - **`docs/ARCHITECTURE.md`**: layered module dependency graph and data flow.
959
+ - **Tour of Numerical Methods** expanded with 2-D quadrature, time-series, and
960
+ filter-design stops.
961
+ - `docs/index.md` Quick Navigation now links the Cookbook, Tour, and Architecture.
962
+
963
+ ### Changed
964
+
965
+ - **`cds.modeling` refactor**: `expression.py` (708 lines) split into
966
+ `_base.py` (AST base classes, visitors) and `_nodes.py` (operator/leaf node
967
+ types). Pure reorganization; no public symbols moved or renamed.
968
+ - **`cds.stats` refactor**: distribution functions (normal/t/chi²/F CDFs and
969
+ inverses) extracted from `hypothesis_tests.py` into the private
970
+ `_distributions.py`, with `__all__` declared so the re-exports pass
971
+ `mypy --strict`.
972
+
973
+ ### Fixed
974
+
975
+ - **`cds.math_utils.linalg`: numerical stability of pivoting.** Pivoting now
976
+ uses a scale-relative threshold (`max(|row|) * epsilon`) instead of a fixed
977
+ absolute epsilon, and rejects exact-zero pivots at sub-normal matrix scales.
978
+ Prevents spurious singular-matrix errors and mis-pivoting on
979
+ small-magnitude matrices. No change to well-scaled inputs.
980
+ - **`cds.stats`**: `__all__` declared so the `_distributions` re-exports are
981
+ recognized as intentional public surface under `mypy --strict`.
982
+ - **Tests**: stabilized a flaky mean-homogeneity property test by anchoring on
983
+ an absolute tolerance instead of a relative one.
984
+
985
+ ## [v1.1.9] - 2026-06-24
986
+
987
+ ### Minor — effect-size measures for the statistics & hypothesis stack
988
+
989
+ A backward-compatible feature release. Adds standardized **effect-size**
990
+ measures to `cds.stats` so users can report the *magnitude* of an effect
991
+ alongside its significance, closing the long-standing gap where a
992
+ hypothesis test answered *"is there an effect?"* but not *"how large?"*.
993
+ No existing API or behavior changes; all prior tests remain green.
994
+
995
+ ### Added
996
+
997
+ - **`cds.stats`: effect-size measures** (`src/cds/stats/hypothesis_tests.py`):
998
+ - `cohens_d(group_a, group_b)`: Cohen's *d* standardized mean difference
999
+ between two samples (pooled-SD denominator).
1000
+ - `eta_squared_from_f(f, df1, df2)`: η² proportion of variance explained
1001
+ by group membership, derived from a one-way ANOVA *F* statistic.
1002
+ - `cramers_v(contingency_table)`: Cramér's *V* association strength for
1003
+ an *r* × *c* contingency table (χ²-based, normalized to `[0, 1]`).
1004
+ All three functions are exported from the top-level `cds.stats` namespace and
1005
+ documented in the tutorial (`docs/tutorials/hypothesis_tests_demo.md`).
1006
+ - **Tutorial section**: *"Effect sizes"* walkthrough in
1007
+ `hypothesis_tests_demo.md` showing how `cohens_d` / `cramers_v` pair with
1008
+ the existing `t_test` / `chi_square_independence` tests.
1009
+ - **Getting-started snippets** (EN + TR) and `docs/index.md` now surface the
1010
+ effect-size functions in the Python-API quick-start and module table.
1011
+
1012
+ ### Documentation
1013
+
1014
+ - README module table, `docs/index.md` Key Features & module description,
1015
+ and the EN/TR getting-started guides now mention effect-size support.
1016
+
1017
+ ## [v1.1.8] - 2026-06-21
1018
+
1019
+ ### Patch — ODE backward integration bug fix
1020
+
1021
+ A user-facing **bug-fix release**. Forward integration is byte-identical
1022
+ to v1.1.7; only the previously-broken `t_end < t0` case changes behavior.
1023
+ Includes corrected deep-verification scripts and a docs sync, no new
1024
+ modules, no API additions.
1025
+
1026
+ ### Fixed
1027
+
1028
+ - **`diffeq.solvers`: backward integration silently returned only the
1029
+ initial value.** The fixed-step (`euler`, `rk4`, `midpoint`) and
1030
+ adaptive (`rk45`) ODE solvers, plus `solve_system`, used a forward-only
1031
+ loop guard `while t < t_end - LOOP_EPSILON`. When `t_end < t0` the
1032
+ guard was immediately `False`, so the solvers did nothing and returned
1033
+ only `y0`. The integration direction is now derived from
1034
+ `copysign(1.0, t_end - t0)` and applied as
1035
+ `direction * min(dt, abs(t_end - t0))`; `dt` stays an unambiguous
1036
+ positive magnitude and the loop guard becomes
1037
+ `(t_end - t) * direction > LOOP_EPSILON`. A zero-length span
1038
+ (`t_end == t0`) still skips the loop because `copysign(1, 0) == +1`.
1039
+ For `rk45`, step size is tracked as an always-positive `h_mag` so the
1040
+ shrink/grow/snap logic keeps its forward semantics in either direction.
1041
+ 7 new `TestBackwardIntegration` regression tests cover all five
1042
+ solvers.
1043
+
1044
+ - **`hypothesis.generator`: confidence overflow past `n >= 12`.** The
1045
+ generated-confidence formula `0.45 + i*0.05` overflowed the
1046
+ `Hypothesis.confidence` `le=1.0` constraint for 12+ hypotheses,
1047
+ raising `ValidationError`. Now clamped to `min(0.9, 0.4 + i*0.05)`.
1048
+
1049
+ ### Changed (verification tooling)
1050
+
1051
+ - **`scripts/verify_d1_numerics.py`, `verify_d2_edge_cases.py`,
1052
+ `verify_d4_hypothesis.py`**, stale reference values/thresholds that
1053
+ produced spurious failures against correct code: D1.3 Romberg
1054
+ monotone-decrease check only asserted above `1e-13`; D1.4 RK45
1055
+ singularity now uses `t_end=2.0` (past the pole) so `RuntimeError` is
1056
+ genuinely triggered; D1.7/D1.2 odd-degree Gauss-Legendre exact
1057
+ integral corrected to `0`; Simpson `O(h^4)` thresholds loosened to
1058
+ match the method's order; D4.2 confidence expectation updated to the
1059
+ clamped formula. All three scripts now report **0 failures**.
1060
+
1061
+ ### Documentation
1062
+
1063
+ - README "recent improvements" → v1.1.8 ODE fix entry; ROADMAP marks
1064
+ hatch-vcs / git-cliff as tried-and-abandoned with the real rollback
1065
+ reasons; SECURITY supported-versions refresh; dashboard UX
1066
+ touch-ups; nav/cross-ref drift. **No code or behavior changes.**
1067
+
1068
+ ## [v1.1.7] - 2026-06-20
1069
+
1070
+ ### Patch — PEP 639 SPDX license metadata
1071
+
1072
+ A maintenance release with **no API or behavior changes**. Standardizes
1073
+ the license declaration so it is recognized as a valid SPDX identifier
1074
+ both on PyPI and in package metadata, and removes drift-prone
1075
+ hardcoded numbers from the README.
1076
+
1077
+ ### Changed
1078
+
1079
+ - **`pyproject.toml`**: adopted [PEP 639](https://peps.python.org/pep-0639/):
1080
+ replaced the legacy `license = {text = "MIT"}` table form with the
1081
+ SPDX `license = "MIT"` expression plus `license-files = ["LICENSE"]`.
1082
+ The wheel/sdist METADATA now emit `License-Expression: MIT` and
1083
+ `License-File: LICENSE`, which PyPI and GitHub recognize as a valid
1084
+ SPDX id (the old table form was not parsed, so the license read as
1085
+ unrecognized). Removed the now-redundant `License :: OSI Approved ::
1086
+ MIT License` classifier (deprecated under PEP 639; would trigger a
1087
+ metadata warning).
1088
+
1089
+ ### Documentation
1090
+
1091
+ - **`README.md`**: removed hardcoded, drift-prone numbers (version
1092
+ tag, test count, module count) in favor of the existing PyPI / CI /
1093
+ codecov badges, so the docs no longer go stale between releases.
1094
+
1095
+ ## [v1.1.6] - 2026-06-20
1096
+
1097
+ ### Patch — release pipeline fix (OIDC → scoped API token)
1098
+
1099
+ A maintenance release with **no API or behavior changes**. Fixes the
1100
+ broken automated release pipeline: the previous Trusted Publishing (OIDC)
1101
+ path required a PyPI publisher configuration that was never set up, so
1102
+ the v1.1.5 tag push failed at the upload step with an `invalid-publisher`
1103
+ error. The pipeline now uses a scoped **PyPI API token** (stored as the
1104
+ `PYPI_API_TOKEN` repo secret), which is the sole publish authority.
1105
+
1106
+ This is the first release actually published by the automated pipeline,
1107
+ v1.1.4 and v1.1.5 were uploaded manually before the pipeline existed.
1108
+
1109
+ ### Changed
1110
+
1111
+ - **`release.yml`**: removed the `id-token: write` permission and the
1112
+ Trusted Publishing path; publishes via `pypa/gh-action-pypi-publish`
1113
+ with `password: ${{ secrets.PYPI_API_TOKEN }}`. The workflow now also
1114
+ creates the GitHub Release (previously done by the local script).
1115
+ - **`scripts/publish.py`**: no longer uploads to PyPI or creates the
1116
+ GitHub release. It now builds, verified the built version against the
1117
+ tag, runs tests, and pushes the tag (which triggers CI). Removed the
1118
+ `--skip-release` flag and the local `~/.pypi-token` handling.
1119
+ - **`pyproject.toml`**: dropped `twine` from the `[all]` and `[dev]`
1120
+ extras (no longer needed locally).
1121
+ - **Version bump `1.1.5` → `1.1.6`** in `pyproject.toml`,
1122
+ `src/cds/_version.py`, and `CITATION.cff`.
1123
+
1124
+ ### Documentation
1125
+
1126
+ - **`README.md`** and **`docs/maintenance.md`**: updated the release
1127
+ pipeline description to reflect the scoped-API-token flow and
1128
+ `release.yml` as the sole publish authority.
1129
+
1130
+ ## [v1.1.5] - 2026-06-20
1131
+
1132
+ ### Patch — quality, type-safety, test depth, and a 100% coverage gate
1133
+
1134
+ A patch release: no API changes, no behavior changes. A coordinated sweep
1135
+ of refactoring (type-safety, code deduplication), deeper testing
1136
+ (property-based invariants, shared fixtures), expanded documentation
1137
+ (tutorials, architecture guide), and a hardening of CI to enforce full
1138
+ blended coverage. The result is the cleanest, most thoroughly verified
1139
+ release to date: **17 modules, 1230 tests, and 100% code coverage
1140
+ (statement + branch)**.
1141
+
1142
+ ### Added
1143
+
1144
+ - **Python 3.13 support**: added 3.13 to the CI test matrix and the
1145
+ `pyproject.toml` classifiers; the full suite is now green on 3.10–3.13.
1146
+ - **Shared test fixtures**: `tests/conftest.py` plus `tests/test_core.py`
1147
+ centralize reusable fixtures and core invariants, reducing duplication
1148
+ across the suite.
1149
+ - **Property-based invariant suite (B5)**: a Hypothesis-driven test set
1150
+ that exercises numerical invariants (associativity, identity,
1151
+ round-trip) over generated inputs, catching edge cases that
1152
+ example-based tests miss.
1153
+ - **Tutorials for optimization, signals, ML, and statistics (B3)**: new
1154
+ guided walkthroughs under `docs/tutorials/` covering the four most-used
1155
+ subsystems.
1156
+ - **Contributing architecture section (B4)**: `CONTRIBUTING.md` now
1157
+ documents the module layout and the data flow between subsystems, with
1158
+ stale cross-references fixed.
1159
+ - **`examples/modeling_demo.py`**: a new end-to-end example demonstrating
1160
+ the modeling workflow referenced by the tutorials.
1161
+
1162
+ ### Changed
1163
+
1164
+ - **Closed remaining `Any` type escapes**: the last untyped boundaries in
1165
+ the core and hypothesis modules now carry concrete types; `mypy --strict`
1166
+ stays green.
1167
+ - **Generic `OptResult`**: the optimization result type is now generic
1168
+ over its scalar type, and the narrowing casts that worked around the old
1169
+ concrete signature have been removed.
1170
+ - **Deduplicated scalar central-difference**: the scalar central-
1171
+ difference implementation that existed in both `calculus` and
1172
+ `optimization` is now shared from a single source.
1173
+ - **Version bump `1.1.4` → `1.1.5`** in `pyproject.toml`,
1174
+ `src/cds/_version.py`, and `CITATION.cff`.
1175
+
1176
+ ### CI
1177
+
1178
+ - **100% blended coverage gate**: CI now fails unless both statement and
1179
+ branch coverage reach 100%, locking in the coverage level as a
1180
+ non-regression boundary.
1181
+ - **Regenerated benchmark report**: the benchmark report and
1182
+ `results.json` were regenerated against the current codebase.
1183
+
1184
+ ### Documentation
1185
+
1186
+ - **Synced stale test count and coverage**: corrected the documented test
1187
+ count (1165 → 1230) and coverage figure (~99.6% → 100%) to match CI.
1188
+ - **Roadmap items shipped**: roadmap entries #2 (modeling) and #3
1189
+ (knowledge organization) are marked released; the corresponding issues
1190
+ are closed.
1191
+
1192
+ ## [v1.1.4] - 2026-06-19
1193
+
1194
+ ### Patch — documentation, CI, and housekeeping cleanup
1195
+
1196
+ A patch release: no API changes, no behavior changes. Removes cosmetic
1197
+ distractions (emojis, sprint references) from issue templates and docs,
1198
+ fixes CI workflow schemas, and deletes ~3 500 lines of no-op autograd
1199
+ shim code that was never exercised at runtime.
1200
+
1201
+ ### Changed
1202
+
1203
+ - **Issue templates**: removed decorative emojis from
1204
+ `bug_report.md`, `config.yml`, and `changelog.yml` for a cleaner,
1205
+ more professional appearance.
1206
+ - **`.github/labeler.yml`**: migrated to the `actions/labeler` v5
1207
+ configuration schema (`triage` → `labels` key).
1208
+ - **`.github/workflows/changelog.yml`**: fixed a missing trailing
1209
+ newline flagged by lint checks.
1210
+ - **Documentation**: stripped sprint-tracking references and
1211
+ ephemeral planning files (`docs/superpowers/plans/`,
1212
+ `docs/superpowers/specs/`); unified inline-code formatting across
1213
+ tutorials and case-study pages.
1214
+ - **Removed no-op autograd shims**: deleted `src/cds/nlp/autograd/`
1215
+ shim functions (`_grad.py` stubs, pass-through wrappers in
1216
+ `ops.py` and `tensor.py`) that were placeholders and never
1217
+ participated in any real gradient computation. ~3 500 lines removed.
1218
+ - **Examples**: aligned `ruff` formatting in
1219
+ `examples/data_analysis_demo.py` and
1220
+ `examples/ml_and_viz_demo.py`.
1221
+ - **Version bump `1.1.3` → `1.1.4`** in `pyproject.toml`,
1222
+ `src/cds/_version.py`, and `CITATION.cff`.
1223
+
1224
+ ## [v1.1.3] - 2026-06-19
1225
+
1226
+ ### Patch — type-safety cleanup
1227
+
1228
+ A patch release: no API changes, no behavior changes. Resolves the final
1229
+ block of `mypy --strict` errors so the type checker reports **0 errors
1230
+ across 136 files**. No public surface changed; all 1165 tests pass and
1231
+ the suite is unchanged.
1232
+
1233
+ ### Fixed
1234
+
1235
+ - **43 `mypy --strict` errors resolved** across `examples/`, `dashboard/`,
1236
+ and `scripts/`. The fixes fall into five categories, none of which
1237
+ alter runtime behavior:
1238
+ - **`int` → `float` argument types**: numeric literals passed to APIs
1239
+ typed as `float` (e.g. integration tolerances, attention scaling)
1240
+ now use explicit `float` literals so the call matches the signature.
1241
+ - **`Domain` enum usage**: iteration and membership checks against the
1242
+ `Domain` enum now go through `Domain.__members__.values()` / explicit
1243
+ member references, matching the pattern established in v1.1.2 for
1244
+ CodeQL compatibility.
1245
+ - **Attention tensor rank**: reshape/transpose calls in
1246
+ `examples/nlp_attention_demo.py` and `examples/nlp_mini_gpt_demo.py`
1247
+ annotated to reflect the actual tensor rank rather than an
1248
+ over-narrow `Any`/scalar guess.
1249
+ - **Invariant list widening**: a few demo helper functions that
1250
+ return heterogeneous sequences now declare `list[object]` (or the
1251
+ specific union) instead of an impossible precise element type.
1252
+ - **`Protocol` signature alignment**: a duck-typed callback protocol
1253
+ in `scripts/publish.py` had a signature that diverged from its
1254
+ concrete implementations; the protocol and call sites now agree.
1255
+
1256
+ ### Changed
1257
+
1258
+ - **Version bump `1.1.2` → `1.1.3`** in `pyproject.toml` and
1259
+ `src/cds/_version.py`.
1260
+
1261
+ ## [v1.1.2] - 2026-06-19
1262
+
1263
+ ### Patch — security hardening & CodeQL closure
1264
+
1265
+ A patch release: no API changes, no behavior changes. Closes the remaining
1266
+ CodeQL code-scanning alerts with a fix (not a workaround),
1267
+ tightens `main` branch protection, and improves the discoverability of the
1268
+ vulnerability-reporting flow. Brings the repo to **0 open** code-scanning
1269
+ alerts (22/22 closed: 20 fixed by code, 2 dismissed as documented false
1270
+ positives).
1271
+
1272
+ ### Security
1273
+
1274
+ - **CodeQL `py/non-iterable-in-for-loop`: fix.** Enum iteration
1275
+ in `examples/core_demo.py` and `tests/test_hypothesis.py` now uses
1276
+ `Domain.__members__.values()` instead of `for x in Domain:`. This is the
1277
+ Enum API's standard member-collection view: functionally identical (same
1278
+ members, same insertion order, all 1164 tests pass) but the return type
1279
+ is an explicitly iterable mapping view that CodeQL's type resolver can
1280
+ follow. Previous attempts (idiomatic iteration, direct import from the
1281
+ defining module) did not satisfy the analyzer; this does, with no
1282
+ camouflage (`list()` wrapping) and no behavior change.
1283
+ - **`main` branch protection strengthened.** Added `required_status_checks`
1284
+ for `CI` and `CodeQL`, a PR can no longer merge into `main` while those
1285
+ checks are red. `enforce_admins` is left disabled so the maintainer
1286
+ retains a direct-push path; everything else (linear history, conversation
1287
+ resolution, no force-pushes, no deletions) is unchanged.
1288
+ - **Security-reporting guidance.** The README now links to `SECURITY.md`
1289
+ and the private-advisory flow; the bug-report issue template warns against
1290
+ opening public issues for vulnerabilities and redirects to private
1291
+ advisories.
1292
+
1293
+ ### Changed
1294
+
1295
+ - **`CITATION.cff` version refresh.** Two stale `1.1.0` references (root and
1296
+ `preferred-citation` blocks) bumped to `1.1.2`. This was missed in v1.1.1.
1297
+
1298
+ ## [v1.1.1] - 2026-06-19
1299
+
1300
+ ### Patch — supply-chain & CI hardening
1301
+
1302
+ A patch release: no API changes, no behavior changes. Strengthens release
1303
+ integrity and CI correctness so downstream consumers and contributors get
1304
+ verifiable, low-churn workflows.
1305
+
1306
+ ### Security
1307
+
1308
+ - **CodeQL static analysis** (`codeql.yml`): runs `security-and-quality`
1309
+ query pack on every push/PR into `main` plus a weekly schedule; findings
1310
+ surface as code-scanning alerts under the Security tab. Complements
1311
+ `attest.yml` (which signs release artifacts with build provenance) and
1312
+ `dependabot.yml` (dependency CVEs).
1313
+ - **README security badge**: live CodeQL status added next to the CI badge.
1314
+
1315
+ ### Changed
1316
+
1317
+ - **`changelog.yml` made idempotent**: all dispatches now target a single
1318
+ fixed branch (`chore/changelog-regen`); `peter-evans/create-pull-request`
1319
+ updates the existing open PR instead of opening a duplicate per tag.
1320
+ Previously up to 6 stale changelog PRs accumulated; now only one is ever
1321
+ open. Also bumped the action `v6 → v7` and added a `concurrency` group to
1322
+ serialize simultaneous dispatches.
1323
+ - **`benchmarks.yml` respects branch protection**: switched from a direct
1324
+ bot push (rejected on protected `main`) to opening a PR via
1325
+ `peter-evans/create-pull-request@v7`, so regenerated artifacts merge
1326
+ through the normal review flow without breaking protection rules.
1327
+
1328
+ ### Removed
1329
+
1330
+ - 6 stale auto-generated changelog PRs (#10, #19, #20, #21, #22, #23) and
1331
+ their per-tag branches, all superseded by the hand-curated CHANGELOG on
1332
+ `main`.
1333
+
1334
+ ## [v1.1.0] - 2026-06-19
1335
+
1336
+ ### Minor — two new modules (symbolic math + knowledge organization)
1337
+
1338
+ A backward-compatible feature release. Adds two new public subpackages
1339
+ (`cds.modeling`, `cds.knowledge`) without changing any existing API. The
1340
+ platform now spans **17 modules**, **1164 tests**, and **99.59%** coverage.
1341
+
1342
+ ### Added
1343
+
1344
+ - **`cds.modeling`**: symbolic algebra for equation development:
1345
+ - An expression tree (`+`, `-`, `*`, `/`, `**`, unary `-`, variables,
1346
+ numbers) built by overloading Python operators on a `Variable`/`Constant`
1347
+ AST.
1348
+ - Symbolic differentiation (`diff`), algebraic simplification
1349
+ (`simplify`), substitution (`subs`), evaluation (`evaluate`), and
1350
+ LaTeX export (`to_latex`).
1351
+ - A `MathModel` for equation systems with `solve_equation` (Newton-Raphson
1352
+ root finding) and `fit_parameters` (least-squares parameter fitting to
1353
+ observations).
1354
+ - Runnable demo (`examples/modeling_demo.py`) + tutorial.
1355
+ - **`cds.knowledge`**: a knowledge-organization layer in three pure-Python,
1356
+ dependency-free files:
1357
+ - `graph.py`: `Concept`, `Relation` (typed directed edges), and a
1358
+ `KnowledgeGraph` with undirected traversal (shortest path via BFS,
1359
+ transitive closure, cycle detection), neighbors, and JSON persistence.
1360
+ - `notes.py`: `Note` + `Notebook` research notebook with tag and
1361
+ concept lookups, and JSON persistence.
1362
+ - `retrieval.py`: `search()` producing ranked `SearchResult` hits across
1363
+ both concepts and notes (matched field + normalized score).
1364
+ - Runnable demo (`examples/knowledge_demo.py`) + tutorial.
1365
+ - Both modules are wired into the package `__all__`, the CLI `modules`
1366
+ listing, and the API reference (`docs/api.md`).
1367
+
1368
+ ### Maintenance
1369
+
1370
+ - Docs: resync README, `docs/index.md`, getting-started (EN + TR), and
1371
+ CITATION.cff to v1.1.0, module count 16→17, test count 883→1164,
1372
+ coverage 99.48%→99.59%. Keep `pyproject.toml` + `src/cds/_version.py`
1373
+ lockstepped at 1.1.0.
1374
+ - Chore(repo): ignore the `_demo_*.json` runtime artifacts the
1375
+ knowledge demo writes next to its script, so a demo run no longer
1376
+ dirties the working tree.
1377
+
1378
+ ## [v1.0.4] - 2026-06-18
1379
+
1380
+ ### Security & Tooling — CI hardening
1381
+
1382
+ A follow-up patch to v1.0.3. No behavior changes to the published package;
1383
+ fully backward compatible. Adds continuous dependency-vulnerability scanning
1384
+ to CI, tightens the type-check configuration, and resynchronizes docs that
1385
+ had drifted after v1.0.0.
1386
+
1387
+ ### Maintenance
1388
+
1389
+ - Chore(ci): add a `pip-audit` job to the CI workflow (`tests.yml`). Runs
1390
+ once on the reference cell (Linux + Python 3.12) against the PyPI Advisory
1391
+ database. Currently `continue-on-error: true`, the dev/docs/test toolchain
1392
+ (jupyter, mkdocs, build, twine, pillow, lxml, ...) carries transitive deps
1393
+ with open CVEs unrelated to the published runtime (typer/pydantic/rich,
1394
+ which audit clean). Surfacing them every run gives visibility without
1395
+ red-flashing the matrix on a fresh advisory.
1396
+ - Chore(types): remove the global `ignore_missing_imports = true` from
1397
+ `[tool.mypy]`. CDS only depends on PEP 561 typed runtime libs (typer,
1398
+ pydantic, rich), all of which resolve cleanly under strict mypy (98 files,
1399
+ 0 errors). Dropping the escape hatch means a future un-stubbed dependency
1400
+ surfaces a real error instead of being silently typed as `Any`.
1401
+ - Chore(repo): delete a stray Windows `nul` artifact left in the working tree.
1402
+ - Docs: resync README + `docs/` after v1.0.0: test count 845→878, version
1403
+ strings updated, `CITATION.cff` bumped to 1.0.4. Keep `pyproject.toml` +
1404
+ `src/cds/_version.py` lockstepped at 1.0.4.
1405
+
1406
+ ## [v1.0.3] - 2026-06-18
1407
+
1408
+ ### Hygiene — test-suite type correctness
1409
+
1410
+ A follow-up patch to v1.0.2. No behavior changes to the published package;
1411
+ fully backward compatible. Brings `tests/` to the same mypy baseline as
1412
+ `src/` so the full type-check (`mypy src/ tests/`) is green, and resolves
1413
+ post-release lint/test/publish findings caught after v1.0.2 shipped.
1414
+
1415
+ ### Testing
1416
+
1417
+ - Test(types): clear all remaining mypy errors across `tests/` (39 files,
1418
+ 0 errors). Fixes list-variance issues (`Parameter <: Tensor`), redundant
1419
+ `type: ignore` comments, and intentional error-path `**` operands.
1420
+ - Test(benchmarks): isolate benchmark test artifacts: `run_all()` /
1421
+ `_write_json()` accept an `output_dir` parameter so `pytest` no longer
1422
+ clobbers the committed `benchmarks/results.json`.
1423
+
1424
+ ### Maintenance
1425
+
1426
+ - Chore(ci): resolve post-1.0.2 lint/test/publish findings (commit 5e429ec).
1427
+ - Docs: keep `pyproject.toml` + `src/cds/_version.py` lockstepped at 1.0.3.
1428
+
1429
+ ## [v1.0.2] - 2026-06-18
1430
+
1431
+ ### Hygiene — test isolation for benchmark artifacts
1432
+
1433
+ A follow-up patch to v1.0.1. No behavior changes to the published package;
1434
+ fully backward compatible. Resolves a repo-hygiene issue where running the
1435
+ benchmark test suite silently clobbered the committed
1436
+ `benchmarks/results.json` artifact (and `docs/benchmarks.md`) on every
1437
+ `pytest` invocation.
1438
+
1439
+ ### Bug Fixes
1440
+
1441
+ - Fix(tests): `test_run_all_generates_report` no longer writes into the
1442
+ working tree. `run_all()` and `_write_json()` now accept an optional
1443
+ `output_dir` parameter; the test passes its `tmp_path`, so the committed
1444
+ `benchmarks/results.json` and `docs/benchmarks.md` are never modified by a
1445
+ test run. Verified: object hash of `results.json` is byte-identical before
1446
+ and after `pytest`.
1447
+
1448
+ ### Testing
1449
+
1450
+ - Test(benchmarks): added a regression assertion that `results.json` lands
1451
+ in `tmp_path` (not `benchmarks/`) after `run_all(output_dir=...)`.
1452
+
1453
+ ### Features
1454
+
1455
+ - Feat(benchmarks): `run_all(output_dir=None)` and
1456
+ `_write_json(record, output_dir=None)`, new optional parameter for
1457
+ redirecting artifact output. Defaults preserve existing CLI behaviour.
1458
+
1459
+ ## [v1.0.1] - 2026-06-18
1460
+
1461
+ ### Maintenance — typed, documented, hardened
1462
+
1463
+ A follow-up to the v1.0 stable release focused on packaging quality and
1464
+ numerical correctness guarantees. No behavior changes; fully backward
1465
+ compatible.
1466
+
1467
+ ### Features
1468
+
1469
+ - Feat(packaging): declare PEP 561 type information: ship `src/cds/py.typed`
1470
+ marker and force-include it in the wheel so downstream users get full
1471
+ static type-checking support out of the box.
1472
+ - Feat(docs): add "type checked" badge to the README.
1473
+
1474
+ ### Testing
1475
+
1476
+ - Test(invariants): add `tests/test_numerical_invariants.py`: 32
1477
+ property-based numerical invariants across 8 modules (linalg, signals,
1478
+ stats, quadrature, quantum, diffeq, monte carlo, probability). Fixed
1479
+ seed, fully reproducible, zero new dev dependencies.
1480
+
1481
+ ### Documentation
1482
+
1483
+ - Docs(api): add docstrings to all 51 previously-undocumented public
1484
+ functions identified via AST scan (3 empty-docstring gaps closed).
1485
+
1486
+ ### Bug Fixes
1487
+
1488
+ - Chore: bump version to 1.0.1.
1489
+
1490
+ ## [v1.0.0] - 2026-06-18
1491
+
1492
+ ### 1.0 — Stable release
1493
+
1494
+ Cognitive Discovery Platform reaches its first stable release. All five
1495
+ subsystems of the v1.0 completion spec are implemented, gated, and
1496
+ verified: 99.16% statement coverage (845 tests passing), zero mypy
1497
+ errors, clean ruff, and a strict mkdocs build.
1498
+
1499
+ ### Features
1500
+
1501
+ - Feat(nlp): NLP visualisation module: attention heatmap, PCA projection, training curve ([7956597](7956597))
1502
+ - Feat(benchmarks): emit results.json with timestamp + git SHA provenance, add CI workflow ([4e18500](4e18500))
1503
+
1504
+ ### Testing
1505
+
1506
+ - Test(coverage): close NLP edge-case gaps: tensor/ops/optim/bpe/layers/model/attention; reach 99.16% statement coverage ([6f0a487](6f0a487))
1507
+ - Style(tests): ruff format cleanup: collapse over-split listcomp, expand train() signature, remove duplicate inline imports ([36f4ee4](36f4ee4))
1508
+
1509
+ ### Documentation
1510
+
1511
+ - Docs(examples): add 9 module demos + matching tutorials ([9f00fc5](9f00fc5))
1512
+ - Docs(api): restructure mkdocs nav, add api.md lead-ins, fix stale test counts ([4cad8be](4cad8be))
1513
+ - Docs(nlp): fix griffe warnings: split combined params in docstrings ([3aedff4](3aedff4))
1514
+ - Docs(benchmarks): regenerate results.json with current SHA provenance ([69c5a88](69c5a88))
1515
+
1516
+ ### Bug Fixes
1517
+
1518
+ - Chore: bump version to 1.0.0 + Production/Stable classifier; sync _version.py
1519
+
1520
+ ### Other
1521
+
1522
+ - Promoted from `Development Status :: 4 - Beta` to `Development Status :: 5 - Production/Stable`.
1523
+
1524
+ ## [v0.10.0b1] - 2026-06-17
1525
+
1526
+
1527
+ ### Features
1528
+
1529
+
1530
+ - Feat(nlp): autograd engine + MiniGPT-from-scratch ([5e0d308](5e0d308))
1531
+
1532
+
1533
+ ### Documentation
1534
+
1535
+
1536
+ - Docs(changelog): regenerate for v0.9.0b8 (#17) ([2b0a7d3](2b0a7d3))
1537
+
1538
+
1539
+ ## [v0.9.0b8] - 2026-06-17
1540
+
1541
+
1542
+ ### Features
1543
+
1544
+
1545
+ - Feat(nlp): add multi-head attention + transformer block ([4f38cae](4f38cae))
1546
+
1547
+
1548
+ ### Documentation
1549
+
1550
+
1551
+ - Docs(changelog): regenerate for v0.9.0b7 (#16) ([44ec93c](44ec93c))
1552
+
1553
+
1554
+ ## [v0.9.0b7] - 2026-06-17
1555
+
1556
+
1557
+ ### Bug Fixes
1558
+
1559
+
1560
+ - Fix: catch two more stale surfaces (CITATION.cff, mkdocs api.md) ([b59b6e3](b59b6e3))
1561
+
1562
+
1563
+ ### Documentation
1564
+
1565
+
1566
+ - Docs(changelog): regenerate for v0.9.0b6 (#15) ([e1244ce](e1244ce))
1567
+
1568
+
1569
+ ## [v0.9.0b6] - 2026-06-17
1570
+
1571
+
1572
+ ### Bug Fixes
1573
+
1574
+
1575
+ - Fix: sync test count 572 to 655 across all surfaces ([952ffe0](952ffe0))
1576
+
1577
+
1578
+ ### Documentation
1579
+
1580
+
1581
+ - Docs(changelog): regenerate for v0.9.0b5 (#14) ([f7a037b](f7a037b))
1582
+
1583
+
1584
+ ## [v0.9.0b5] - 2026-06-17
1585
+
1586
+
1587
+ ### Features
1588
+
1589
+
1590
+ - Feat(nlp): add cds.nlp module: BPE tokenizer + sinusoidal embeddings ([045b9d1](045b9d1))
1591
+
1592
+
1593
+ ### Other
1594
+
1595
+
1596
+ - Build: drop hatch-vcs + setuptools_scm, switch to static versioning ([6e04d31](6e04d31))
1597
+
1598
+
1599
+ ### Documentation
1600
+
1601
+
1602
+ - Docs(changelog): regenerate for v0.9.0b4 (#13) ([da52ee0](da52ee0))
1603
+
1604
+
1605
+ ## [v0.9.0b4] - 2026-06-17
1606
+
1607
+
1608
+ ### Bug Fixes
1609
+
1610
+
1611
+ - Fix: drop stale 'auditor' comment + sync 570 to 572 across docs and cli ([0dcaba6](0dcaba6))
1612
+
1613
+
1614
+ ### Documentation
1615
+
1616
+
1617
+ - Docs(changelog): regenerate for v0.9.0b4 (#11) ([b1eda78](b1eda78))
1618
+
1619
+
1620
+ ## [v0.9.0b3] - 2026-06-17
1621
+
1622
+
1623
+ ### Bug Fixes
1624
+
1625
+
1626
+ - Fix(docs): include getting-started.tr.md in mkdocs nav; fix broken CONTRIBUTING link ([85316fe](85316fe))
1627
+
1628
+ - Fix: bump CITATION.cff top-level version to 0.9.0b2 ([80cc3b4](80cc3b4))
1629
+
1630
+ - Fix: bump CITATION.cff top-level version to 0.9.0b2 (was 0.8.5, missed during release) ([adee53c](adee53c))
1631
+
1632
+ - Fix: keep cast() in test_legendre (Python 3.10/3.11 mypy needs it, 3.12 ignores) ([bcd20fc](bcd20fc))
1633
+
1634
+ - Fix: resolve 34 mypy errors (matrix/fft type unions, plot float types, missing confidence arg, cli.Path) ([eea36a3](eea36a3))
1635
+
1636
+ - Fix: type local _legendre import as Callable[[int, float], tuple[float, float]] (cross-Python mypy fix) ([486bad5](486bad5))
1637
+
1638
+ - Fix: use # type: ignore[no-any-return] instead of cast() for cross-Python compat ([bd3aaa8](bd3aaa8))
1639
+
1640
+
1641
+ ### Other
1642
+
1643
+
1644
+ - Build: add setuptools_scm local-scheme config (no-local-version, fallback) ([82d07c9](82d07c9))
1645
+
1646
+ - Build: exclude hatch-vcs generated _version.py from ruff ([76760d3](76760d3))
1647
+
1648
+ - Build: publish.py ignores hatch-vcs regenerated _version.py in dirty check ([bea5f71](bea5f71))
1649
+
1650
+ - Build: setuptools_scm version_scheme=no-guess-dev; fix wheel version regex ([8ccb292](8ccb292))
1651
+
1652
+ - Release: v0.9.0b1 - Beta milestone, CI multi-OS, hatch-vcs, git-cliff, attestation ([3e3928f](3e3928f))
1653
+
1654
+ - Release: v0.9.0b2 - same code, re-tag to trigger attest workflow (checkout fix) ([c54e900](c54e900))
1655
+
1656
+ - Release: v0.9.0b3 - branch protection, threat model, i18n, signed commits guide ([31983fe](31983fe))
1657
+
1658
+
1659
+ ### Documentation
1660
+
1661
+
1662
+ - Docs(changelog): regenerate for v0.9.0b1 ([44f7823](44f7823))
1663
+
1664
+ - Docs(changelog): regenerate for v0.9.0b2 ([404532c](404532c))
1665
+
1666
+ - Docs(changelog): regenerate for v0.9.0b3 (#8) ([3a8ef95](3a8ef95))
1667
+
1668
+ - Docs(changelog): regenerate for v0.9.0b3 (#9) ([c4fcb9b](c4fcb9b))
1669
+
1670
+ - Docs: add threat model, signed commits guide, Why CDS comparison, Turkish i18n; update ROADMAP ([0ba07cf](0ba07cf))
1671
+
1672
+ - Docs: update SECURITY.md supported versions (0.6.x → 0.8.x) ([b42cf5f](b42cf5f))
1673
+
1674
+
1675
+ ### Styling
1676
+
1677
+
1678
+ - Style: pre-commit auto-fix (trailing whitespace, import order, ruff format) ([9adbf5a](9adbf5a))
1679
+
1680
+ - Style: pre-commit auto-fix _version.py (add blank line before __version__) ([277b535](277b535))
1681
+
1682
+
1683
+ ### Miscellaneous Tasks
1684
+
1685
+
1686
+ - Ci: changelog PR action needs explicit base branch (checked out on tag) ([b96d322](b96d322))
1687
+
1688
+ - Ci: changelog action checks out main (not tag) to avoid detached HEAD issues ([af3cd12](af3cd12))
1689
+
1690
+ - Ci: changelog workflow needs write contents + pull-requests perms ([a319a9f](a319a9f))
1691
+
1692
+ - Ci: changelog workflow uses PR instead of direct push (branch protection compat) ([3f593cb](3f593cb))
1693
+
1694
+ - Ci: fix attest + changelog workflows (checkout step, detached HEAD push) ([d2c9d6e](d2c9d6e))
1695
+
1696
+ - Ci: quote step name with colon (YAML parse error) ([0731ca8](0731ca8))
1697
+
1698
+ - Ci: rewrite tests.yml with simple bash conditional (no GitHub conditional parse issues) ([2cc8483](2cc8483))
1699
+
1700
+ - Ci: split test step into 2 by matrix (gate vs report-only) - fix missing fi ([9e68ff0](9e68ff0))
1701
+
1702
+
1703
+ ## [v0.8.5] - 2026-06-16
1704
+
1705
+
1706
+ ### Other
1707
+
1708
+
1709
+ - Release: v0.8.5 - cds[all] extras, auto-generated API ref, docs deploy ([12b03b0](12b03b0))
1710
+
1711
+
1712
+ ## [v0.8.4] - 2026-06-16
1713
+
1714
+
1715
+ ### Other
1716
+
1717
+
1718
+ - Release: v0.8.4 - pydantic upgrade ([58ee8d9](58ee8d9))
1719
+
1720
+
1721
+ ## [v0.8.3] - 2026-06-16
1722
+
1723
+
1724
+ ### Other
1725
+
1726
+
1727
+ - Release: v0.8.3 - example guard consistency ([5017680](5017680))
1728
+
1729
+
1730
+ ## [v0.8.2] - 2026-06-16
1731
+
1732
+
1733
+ ### Other
1734
+
1735
+
1736
+ - Release: v0.8.2 - docstrings, knowledge/ removal, CHANGELOG backfill ([f22150c](f22150c))
1737
+
1738
+ - Scripts: replace publish.ps1 with pure-Python publish.py ([c7c08e2](c7c08e2))
1739
+
1740
+
1741
+ ### Miscellaneous Tasks
1742
+
1743
+
1744
+ - Ci: fix pre-commit and coverage gate for stable CI ([ca66c9f](ca66c9f))
1745
+
1746
+ - Ci: remove Docs workflow; relax coverage gate; re-enable legacy Pages ([cdcf5d0](cdcf5d0))
1747
+
1748
+
1749
+ ## [v0.8.1] - 2026-06-16
1750
+
1751
+
1752
+ ### Other
1753
+
1754
+
1755
+ - Release: v0.8.1 ([4dc49e2](4dc49e2))
1756
+
1757
+
1758
+ ### Documentation
1759
+
1760
+
1761
+ - Docs(roadmap): link open enhancement issues #2 and #3 under Longer Term ([ee6103b](ee6103b))
1762
+
1763
+ - Docs: mark v0.8.0 as released; move 3 pending perf items to v0.8.1 ([80e6afe](80e6afe))
1764
+
1765
+
1766
+ ### Testing
1767
+
1768
+
1769
+ - Test: hit 100% statement coverage; keep branch coverage off ([5c606c4](5c606c4))
1770
+
1771
+
1772
+ ### Miscellaneous Tasks
1773
+
1774
+
1775
+ - Ci(pypi): fix pypi-publish workflow ([8335cb6](8335cb6))
1776
+
1777
+ - Ci(scripts): add publish.ps1 for local PyPI releases ([57e81a4](57e81a4))
1778
+
1779
+ - Ci: harden repo to 10/10 - pre-commit, lockfiles, coverage gate ([7c3b18f](7c3b18f))
1780
+
1781
+ - Ci: remove pypi-publish workflow ([043b7f5](043b7f5))
1782
+
1783
+
1784
+ ## [v0.8.0] - 2026-06-16
1785
+
1786
+
1787
+ ### Other
1788
+
1789
+
1790
+ - Squashed: collapse 108 commits into a single cohesive history ([d4e8aee](d4e8aee))
1791
+
1792
+ - Release: v0.8.0 - Performance & Benchmarks ([83211ef](83211ef))
1793
+
1794
+
1795
+ <!-- generated by git-cliff -->