solverforge 0.5.0__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. {solverforge-0.5.0 → solverforge-0.6.0}/.github/workflows/release.yml +18 -6
  2. {solverforge-0.5.0 → solverforge-0.6.0}/AGENTS.md +36 -4
  3. {solverforge-0.5.0 → solverforge-0.6.0}/CHANGELOG.md +8 -0
  4. {solverforge-0.5.0 → solverforge-0.6.0}/Cargo.lock +13 -13
  5. {solverforge-0.5.0 → solverforge-0.6.0}/Cargo.toml +8 -8
  6. {solverforge-0.5.0 → solverforge-0.6.0}/Makefile +13 -2
  7. solverforge-0.6.0/PKG-INFO +416 -0
  8. solverforge-0.6.0/README.md +384 -0
  9. solverforge-0.6.0/WIREFRAME.md +456 -0
  10. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/README.md +15 -10
  11. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/api/dto.py +18 -0
  12. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/data/data_seed/entrypoints.py +1 -65
  13. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/domain/metrics.py +121 -32
  14. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/domain/plan.py +42 -0
  15. solverforge-0.6.0/examples/solverforge_deliveries/src/domain/vehicle.py +112 -0
  16. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/README.md +12 -7
  17. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/solver.toml +2 -2
  18. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/api/dto.py +18 -0
  19. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/domain/plan.py +52 -7
  20. {solverforge-0.5.0 → solverforge-0.6.0}/pyproject.toml +1 -1
  21. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/__init__.py +26 -2
  22. solverforge-0.6.0/python/solverforge/_native.pyi +72 -0
  23. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/config.py +27 -3
  24. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/constraints.py +50 -18
  25. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/decorators.py +102 -14
  26. solverforge-0.6.0/python/solverforge/fields.py +494 -0
  27. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/groups.py +70 -2
  28. solverforge-0.6.0/python/solverforge/joiner.py +39 -0
  29. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/manager.py +31 -5
  30. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/model.py +167 -6
  31. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/solver.py +6 -4
  32. {solverforge-0.5.0 → solverforge-0.6.0}/src/bindings.rs +6 -0
  33. solverforge-0.6.0/src/config.rs +113 -0
  34. solverforge-0.6.0/src/constraints/compiled.rs +322 -0
  35. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/list_precedence.rs +222 -54
  36. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/mod.rs +1 -0
  37. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/state.rs +411 -105
  38. solverforge-0.6.0/src/error.rs +44 -0
  39. solverforge-0.6.0/src/manager/candidate_trace.rs +388 -0
  40. solverforge-0.6.0/src/manager/events.rs +564 -0
  41. {solverforge-0.5.0 → solverforge-0.6.0}/src/manager/jobs.rs +102 -27
  42. solverforge-0.6.0/src/manager/mod.rs +7 -0
  43. solverforge-0.6.0/src/manager/provenance.rs +205 -0
  44. solverforge-0.6.0/src/runtime/candidate_metric.rs +119 -0
  45. solverforge-0.6.0/src/runtime/dynamic_assignment_group.rs +471 -0
  46. solverforge-0.6.0/src/runtime/dynamic_provider.rs +291 -0
  47. solverforge-0.6.0/src/runtime/list_slots.rs +798 -0
  48. solverforge-0.6.0/src/runtime/mod.rs +46 -0
  49. solverforge-0.6.0/src/runtime/scalar_slots.rs +337 -0
  50. solverforge-0.6.0/src/schema/compiled.rs +43 -0
  51. {solverforge-0.5.0 → solverforge-0.6.0}/src/schema/mod.rs +2 -0
  52. solverforge-0.6.0/src/schema/parse.rs +760 -0
  53. solverforge-0.6.0/src/schema/runtime_plan.rs +71 -0
  54. solverforge-0.6.0/src/schema/types.rs +266 -0
  55. solverforge-0.6.0/src/schema/validate.rs +118 -0
  56. {solverforge-0.5.0 → solverforge-0.6.0}/src/solver/api.rs +29 -51
  57. {solverforge-0.5.0 → solverforge-0.6.0}/src/solver/console.rs +14 -15
  58. solverforge-0.6.0/src/solver/solvable.rs +53 -0
  59. solverforge-0.6.0/src/state/callback_view.rs +616 -0
  60. solverforge-0.6.0/src/state/entity_table.rs +143 -0
  61. solverforge-0.6.0/src/state/marshal.rs +1195 -0
  62. solverforge-0.6.0/src/state/solution.rs +844 -0
  63. solverforge-0.6.0/src/state/variables.rs +18 -0
  64. solverforge-0.6.0/tests/python/test_candidate_trace_provenance.py +174 -0
  65. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_config.py +37 -8
  66. solverforge-0.6.0/tests/python/test_constraints.py +1440 -0
  67. solverforge-0.6.0/tests/python/test_decorators.py +606 -0
  68. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_deliveries_example.py +64 -13
  69. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_deliveries_frontend_app.py +36 -2
  70. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_hospital_example.py +33 -3
  71. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_hospital_frontend_app.py +38 -3
  72. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_list_solving.py +785 -168
  73. solverforge-0.6.0/tests/python/test_manager.py +372 -0
  74. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_release_metadata.py +3 -5
  75. solverforge-0.6.0/tests/python/test_scalar_solving.py +3275 -0
  76. solverforge-0.6.0/tests/python/test_tracebacks.py +185 -0
  77. solverforge-0.6.0/tests/rust/constraint_set.rs +45 -0
  78. {solverforge-0.5.0 → solverforge-0.6.0}/tests/rust/descriptor.rs +14 -8
  79. solverforge-0.6.0/tests/rust/runtime_slots.rs +226 -0
  80. {solverforge-0.5.0 → solverforge-0.6.0}/tests/rust/state_clone.rs +113 -33
  81. solverforge-0.5.0/PKG-INFO +0 -336
  82. solverforge-0.5.0/README.md +0 -304
  83. solverforge-0.5.0/WIREFRAME.md +0 -306
  84. solverforge-0.5.0/examples/solverforge_deliveries/src/domain/vehicle.py +0 -41
  85. solverforge-0.5.0/python/solverforge/_native.pyi +0 -30
  86. solverforge-0.5.0/python/solverforge/fields.py +0 -133
  87. solverforge-0.5.0/python/solverforge/joiner.py +0 -28
  88. solverforge-0.5.0/src/config.rs +0 -58
  89. solverforge-0.5.0/src/error.rs +0 -9
  90. solverforge-0.5.0/src/manager/events.rs +0 -154
  91. solverforge-0.5.0/src/manager/mod.rs +0 -4
  92. solverforge-0.5.0/src/runtime/distance.rs +0 -17
  93. solverforge-0.5.0/src/runtime/dynamic_scalar_search.rs +0 -6307
  94. solverforge-0.5.0/src/runtime/list_slots.rs +0 -28
  95. solverforge-0.5.0/src/runtime/mod.rs +0 -32
  96. solverforge-0.5.0/src/runtime/scalar_slots.rs +0 -29
  97. solverforge-0.5.0/src/runtime/static_fns.rs +0 -21
  98. solverforge-0.5.0/src/runtime/thread_local.rs +0 -21
  99. solverforge-0.5.0/src/schema/parse.rs +0 -260
  100. solverforge-0.5.0/src/schema/types.rs +0 -112
  101. solverforge-0.5.0/src/schema/validate.rs +0 -38
  102. solverforge-0.5.0/src/solver/solvable.rs +0 -60
  103. solverforge-0.5.0/src/state/callback_view.rs +0 -294
  104. solverforge-0.5.0/src/state/entity_table.rs +0 -51
  105. solverforge-0.5.0/src/state/marshal.rs +0 -349
  106. solverforge-0.5.0/src/state/solution.rs +0 -465
  107. solverforge-0.5.0/src/state/variables.rs +0 -22
  108. solverforge-0.5.0/tests/python/test_constraints.py +0 -638
  109. solverforge-0.5.0/tests/python/test_decorators.py +0 -53
  110. solverforge-0.5.0/tests/python/test_manager.py +0 -82
  111. solverforge-0.5.0/tests/python/test_scalar_solving.py +0 -1530
  112. solverforge-0.5.0/tests/python/test_tracebacks.py +0 -40
  113. solverforge-0.5.0/tests/rust/constraint_set.rs +0 -38
  114. solverforge-0.5.0/tests/rust/runtime_slots.rs +0 -108
  115. {solverforge-0.5.0 → solverforge-0.6.0}/.github/workflows/ci.yml +0 -0
  116. {solverforge-0.5.0 → solverforge-0.6.0}/.gitignore +0 -0
  117. {solverforge-0.5.0 → solverforge-0.6.0}/.pre-commit-config.yaml +0 -0
  118. {solverforge-0.5.0 → solverforge-0.6.0}/.python-version +0 -0
  119. {solverforge-0.5.0 → solverforge-0.6.0}/LICENSE +0 -0
  120. {solverforge-0.5.0 → solverforge-0.6.0}/examples/list_tsp.py +0 -0
  121. {solverforge-0.5.0 → solverforge-0.6.0}/examples/mixed_job_shop.py +0 -0
  122. {solverforge-0.5.0 → solverforge-0.6.0}/examples/nqueens.py +0 -0
  123. {solverforge-0.5.0 → solverforge-0.6.0}/examples/shift_scheduling.py +0 -0
  124. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/__init__.py +0 -0
  125. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/__main__.py +0 -0
  126. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/solver.toml +0 -0
  127. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/__init__.py +0 -0
  128. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/api/__init__.py +0 -0
  129. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/api/mod.py +0 -0
  130. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/api/routes.py +0 -0
  131. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/api/sse.py +0 -0
  132. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/constraints/__init__.py +0 -0
  133. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/constraints/mod.py +0 -0
  134. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/data/__init__.py +0 -0
  135. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/data/data_seed/__init__.py +0 -0
  136. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/data/data_seed/locations.json +0 -0
  137. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/data/mod.py +0 -0
  138. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/domain/__init__.py +0 -0
  139. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/domain/delivery.py +0 -0
  140. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/domain/mod.py +0 -0
  141. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/lib.py +0 -0
  142. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/main.py +0 -0
  143. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/solver/__init__.py +0 -0
  144. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/solver/mod.py +0 -0
  145. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/solver/service/__init__.py +0 -0
  146. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/solver/service/mod.py +0 -0
  147. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/src/solver/service/payload.py +0 -0
  148. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/main.mjs +0 -0
  149. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/models/core.mjs +0 -0
  150. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/models/formatters.mjs +0 -0
  151. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/models/preview.mjs +0 -0
  152. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/models/timeline.mjs +0 -0
  153. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/models.mjs +0 -0
  154. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/api-guide.mjs +0 -0
  155. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/components.mjs +0 -0
  156. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/data-tables.mjs +0 -0
  157. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/layout.mjs +0 -0
  158. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/lifecycle.mjs +0 -0
  159. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/modals.mjs +0 -0
  160. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app/ui/overview.mjs +0 -0
  161. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app.css +0 -0
  162. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/app.js +0 -0
  163. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/generated/ui-model.json +0 -0
  164. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/index.html +0 -0
  165. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_deliveries/static/sf-config.json +0 -0
  166. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/__init__.py +0 -0
  167. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/__main__.py +0 -0
  168. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/__init__.py +0 -0
  169. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/api/__init__.py +0 -0
  170. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/api/mod.py +0 -0
  171. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/api/routes.py +0 -0
  172. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/api/sse.py +0 -0
  173. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/__init__.py +0 -0
  174. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/assigned_shift.py +0 -0
  175. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/balance_assignments.py +0 -0
  176. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/desired_day.py +0 -0
  177. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/minimum_rest.py +0 -0
  178. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/mod.py +0 -0
  179. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/one_shift_per_day.py +0 -0
  180. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/overlapping_shift.py +0 -0
  181. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/required_skill.py +0 -0
  182. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/unavailable_employee.py +0 -0
  183. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/constraints/undesired_day.py +0 -0
  184. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/__init__.py +0 -0
  185. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/LARGE.json +0 -0
  186. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/__init__.py +0 -0
  187. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/availability.py +0 -0
  188. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/cohorts.py +0 -0
  189. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/coverage.py +0 -0
  190. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/demand.py +0 -0
  191. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/employees.py +0 -0
  192. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/entrypoints.py +0 -0
  193. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/large.py +0 -0
  194. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/preferences.py +0 -0
  195. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/shifts.py +0 -0
  196. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/skills.py +0 -0
  197. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/time_utils.py +0 -0
  198. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/validation.py +0 -0
  199. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/vocabulary.py +0 -0
  200. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/data_seed/witness.py +0 -0
  201. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/data/mod.py +0 -0
  202. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/domain/__init__.py +0 -0
  203. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/domain/care_hub.py +0 -0
  204. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/domain/employee.py +0 -0
  205. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/domain/mod.py +0 -0
  206. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/lib.py +0 -0
  207. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/main.py +0 -0
  208. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/solver/__init__.py +0 -0
  209. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/solver/mod.py +0 -0
  210. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/solver/service/__init__.py +0 -0
  211. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/solver/service/mod.py +0 -0
  212. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/src/solver/service/payload.py +0 -0
  213. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/main.mjs +0 -0
  214. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/analysis-modal.mjs +0 -0
  215. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/datetime.mjs +0 -0
  216. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/employee-view.mjs +0 -0
  217. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/grouping.mjs +0 -0
  218. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/identity.mjs +0 -0
  219. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/location-view.mjs +0 -0
  220. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/presentation.mjs +0 -0
  221. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/schedule/rail-renderer.mjs +0 -0
  222. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/api-guide.mjs +0 -0
  223. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/app-shell.mjs +0 -0
  224. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/app-state.mjs +0 -0
  225. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/config-loader.mjs +0 -0
  226. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/data-panel.mjs +0 -0
  227. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/shell/solver-controller.mjs +0 -0
  228. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/app/views/registry.mjs +0 -0
  229. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/generated/ui-model.json +0 -0
  230. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/index.html +0 -0
  231. {solverforge-0.5.0 → solverforge-0.6.0}/examples/solverforge_hospital/static/sf-config.json +0 -0
  232. {solverforge-0.5.0 → solverforge-0.6.0}/examples/vrp_owner_hooks.py +0 -0
  233. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/console.py +0 -0
  234. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/errors.py +0 -0
  235. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/events.py +0 -0
  236. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/py.typed +0 -0
  237. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/score.py +0 -0
  238. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/typing.py +0 -0
  239. {solverforge-0.5.0 → solverforge-0.6.0}/python/solverforge/ui.py +0 -0
  240. {solverforge-0.5.0 → solverforge-0.6.0}/rust-toolchain.toml +0 -0
  241. {solverforge-0.5.0 → solverforge-0.6.0}/scripts/verify_release_artifacts.py +0 -0
  242. {solverforge-0.5.0 → solverforge-0.6.0}/scripts/verify_solverforge_release_base.py +0 -0
  243. {solverforge-0.5.0 → solverforge-0.6.0}/src/callbacks/call.rs +0 -0
  244. {solverforge-0.5.0 → solverforge-0.6.0}/src/callbacks/mod.rs +0 -0
  245. {solverforge-0.5.0 → solverforge-0.6.0}/src/callbacks/registry.rs +0 -0
  246. {solverforge-0.5.0 → solverforge-0.6.0}/src/callbacks/threading.rs +0 -0
  247. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/evaluate.rs +0 -0
  248. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/incremental.rs +0 -0
  249. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/matches.rs +0 -0
  250. {solverforge-0.5.0 → solverforge-0.6.0}/src/constraints/stream_plan.rs +0 -0
  251. {solverforge-0.5.0 → solverforge-0.6.0}/src/descriptor/extractor.rs +0 -0
  252. {solverforge-0.5.0 → solverforge-0.6.0}/src/descriptor/mod.rs +0 -0
  253. {solverforge-0.5.0 → solverforge-0.6.0}/src/descriptor/variable.rs +0 -0
  254. {solverforge-0.5.0 → solverforge-0.6.0}/src/intern.rs +0 -0
  255. {solverforge-0.5.0 → solverforge-0.6.0}/src/lib.rs +0 -0
  256. {solverforge-0.5.0 → solverforge-0.6.0}/src/proxy/entity.rs +0 -0
  257. {solverforge-0.5.0 → solverforge-0.6.0}/src/proxy/list.rs +0 -0
  258. {solverforge-0.5.0 → solverforge-0.6.0}/src/proxy/mod.rs +0 -0
  259. {solverforge-0.5.0 → solverforge-0.6.0}/src/proxy/solution.rs +0 -0
  260. {solverforge-0.5.0 → solverforge-0.6.0}/src/schema/build.rs +0 -0
  261. {solverforge-0.5.0 → solverforge-0.6.0}/src/schema/python.rs +0 -0
  262. {solverforge-0.5.0 → solverforge-0.6.0}/src/score.rs +0 -0
  263. {solverforge-0.5.0 → solverforge-0.6.0}/src/solver/mod.rs +0 -0
  264. {solverforge-0.5.0 → solverforge-0.6.0}/src/solver/progress.rs +0 -0
  265. {solverforge-0.5.0 → solverforge-0.6.0}/src/solver/result.rs +0 -0
  266. {solverforge-0.5.0 → solverforge-0.6.0}/src/state/clone.rs +0 -0
  267. {solverforge-0.5.0 → solverforge-0.6.0}/src/state/mod.rs +0 -0
  268. {solverforge-0.5.0 → solverforge-0.6.0}/src/ui.rs +0 -0
  269. {solverforge-0.5.0 → solverforge-0.6.0}/src/value.rs +0 -0
  270. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_examples_import_surface.py +0 -0
  271. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_examples_playwright.py +0 -0
  272. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_mixed_solving.py +0 -0
  273. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_threading.py +0 -0
  274. {solverforge-0.5.0 → solverforge-0.6.0}/tests/python/test_ui_assets.py +0 -0
  275. {solverforge-0.5.0 → solverforge-0.6.0}/tests/rust/manager.rs +0 -0
  276. {solverforge-0.5.0 → solverforge-0.6.0}/tests/rust/score.rs +0 -0
  277. {solverforge-0.5.0 → solverforge-0.6.0}/tests/rust.rs +0 -0
@@ -14,10 +14,18 @@ env:
14
14
  RUST_VERSION: "1.95.0"
15
15
 
16
16
  jobs:
17
+ forgejo-release-guard:
18
+ name: Forgejo release guard
19
+ if: github.server_url != 'https://github.com'
20
+ runs-on: rust
21
+ steps:
22
+ - name: Skip publish-only release workflow
23
+ run: echo "Release publishing runs only on GitHub; Forgejo tag CI is intentionally a no-op."
24
+
17
25
  sdist:
18
26
  name: source distribution
19
27
  if: github.server_url == 'https://github.com'
20
- runs-on: ubuntu-latest
28
+ runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'rust' }}
21
29
  steps:
22
30
  - name: Checkout solverforge-py
23
31
  uses: actions/checkout@v6
@@ -48,7 +56,7 @@ jobs:
48
56
  wheels:
49
57
  name: wheel ${{ matrix.os }} ${{ matrix.target }}
50
58
  if: github.server_url == 'https://github.com'
51
- runs-on: ${{ matrix.os }}
59
+ runs-on: ${{ github.server_url == 'https://github.com' && matrix.os || 'rust' }}
52
60
  strategy:
53
61
  fail-fast: false
54
62
  matrix:
@@ -95,7 +103,7 @@ jobs:
95
103
  verify:
96
104
  name: verify artifacts
97
105
  if: github.server_url == 'https://github.com'
98
- runs-on: ubuntu-latest
106
+ runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'rust' }}
99
107
  needs: [sdist, wheels]
100
108
  steps:
101
109
  - name: Checkout solverforge-py
@@ -132,15 +140,16 @@ jobs:
132
140
 
133
141
  publish-testpypi:
134
142
  name: publish to TestPyPI
135
- runs-on: ubuntu-latest
143
+ runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'rust' }}
136
144
  needs: verify
137
145
  if: >-
146
+ always() &&
147
+ needs.verify.result == 'success' &&
138
148
  github.server_url == 'https://github.com' &&
139
149
  github.event_name == 'workflow_dispatch'
140
150
  environment: testpypi
141
151
  permissions:
142
152
  contents: read
143
- id-token: write
144
153
  steps:
145
154
  - name: Download verified distributions
146
155
  uses: actions/download-artifact@v8
@@ -152,12 +161,15 @@ jobs:
152
161
  uses: pypa/gh-action-pypi-publish@release/v1
153
162
  with:
154
163
  repository-url: https://test.pypi.org/legacy/
164
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
155
165
 
156
166
  publish-pypi:
157
167
  name: publish to PyPI
158
- runs-on: ubuntu-latest
168
+ runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'rust' }}
159
169
  needs: verify
160
170
  if: >-
171
+ always() &&
172
+ needs.verify.result == 'success' &&
161
173
  github.server_url == 'https://github.com' &&
162
174
  github.event_name == 'push' &&
163
175
  startsWith(github.ref, 'refs/tags/v')
@@ -73,6 +73,14 @@ bridge seams. This checkout consumes public upstream crates through exact
73
73
  registry pins in `Cargo.toml` and `Cargo.lock`; do not add private upstream
74
74
  module dependencies or local path overrides for release work.
75
75
 
76
+ One compiled schema owns one immutable runtime plan: parsed schema, descriptor,
77
+ upstream `RuntimeModel`, assignment bindings, constraints, and candidate metrics.
78
+ Direct solves, retained jobs, snapshots, clones, and resumes must use that same
79
+ plan; do not recreate wrapper-local phases, selector trees, move types, TLS slot
80
+ state, or fallback construction paths. Schema caching is allowed only for
81
+ structurally stable, capture-free callback state; stateful callbacks compile per
82
+ invocation.
83
+
76
84
  Python callbacks are the only constraint authoring surface. Callback exceptions
77
85
  must preserve actionable Python tracebacks. Callback solution views must expose
78
86
  ordinary solution-level lookup context while projecting entity/fact collections
@@ -80,6 +88,28 @@ from Rust-owned state. Callback code may be called many times and from multiple
80
88
  worker threads on CPython 3.14 free-threaded, so treat solution-level lookup
81
89
  context as immutable during a solve.
82
90
 
91
+ `@candidate_metric` callbacks are the Python surface for named sorted or
92
+ probabilistic selector metrics. Register them through
93
+ `@planning_solution(..., candidate_metrics=[...])`; they receive the callback
94
+ solution view plus a canonical candidate identity and must return finite numeric
95
+ values. `selection_metric` is valid only with `sorted` or `probabilistic`
96
+ selection order, and probabilistic weights must be non-negative.
97
+
98
+ Ordinary dynamic scalar construction supports `first_fit` and
99
+ `cheapest_insertion`. Assignment-group construction also supports the decreasing,
100
+ weakest-fit, and strongest-fit scalar variants when their declared `entity_order`
101
+ and `value_order` capabilities satisfy the upstream compiler. Dynamic list
102
+ construction supports round-robin, cheapest/regret insertion, Clarke-Wright, and
103
+ K-opt; route-aware variants require their explicit savings or route metadata.
104
+
105
+ Candidate traces are bounded, opt-in retained diagnostics. Keep them out of
106
+ synchronous `Solver.solve`, ordinary statuses, and events; expose them only
107
+ through the atomic `SolverManager.telemetry_detail` payload. Qualified traces
108
+ require an explicit per-job `QualifiedCandidateTraceProvenance` with five
109
+ lowercase SHA-256 digests and a non-blank external producer. Never infer those
110
+ values from a solution, environment, callback, or file, and never accept
111
+ qualified provenance through serializable `SolverConfig`.
112
+
83
113
  Do not fake unsupported behavior. Top-level `ConstraintFactory.join`,
84
114
  `group_by`, `if_exists`, `if_not_exists`, and `flattened` remain explicit
85
115
  unsupported methods until public bridge support exists for those top-level
@@ -92,16 +122,18 @@ claimed as Python-bindable without a public upstream seam.
92
122
  example dependencies, project URLs, classifiers, and maturin module settings.
93
123
  `Cargo.toml` owns native crate metadata and the SolverForge Rust dependency
94
124
  base; the package version must match `pyproject.toml`. `Cargo.lock` locks
95
- reproducible Rust builds. The `Makefile` owns local release targets,
125
+ reproducible Rust builds. The current release line is package/crate `0.6.0` on
126
+ the six SolverForge `0.18.0` registry crates and `solverforge-ui` `0.7.0`;
127
+ `make release-base-check` must stay green. The `Makefile` owns local release targets,
96
128
  dependency-base checks, distribution builds, artifact validation, browser system
97
129
  dependency setup, and `pre-release`. `.github/workflows/ci.yml` validates source
98
130
  checkouts on GitHub and Forgejo, installs Playwright system dependencies on
99
131
  Linux, and retries network toolchain bootstraps for transient runner DNS misses.
100
132
  `.github/workflows/release.yml` builds sdists/wheels, verifies release
101
133
  artifacts, publishes to TestPyPI only from manual workflow dispatch, and
102
- publishes to PyPI only from a matching `v*.*.*` tag after the reviewed `pypi`
103
- environment approves the job. `scripts/verify_release_artifacts.py` checks
104
- deterministic artifact metadata/content, and
134
+ publishes to PyPI automatically from a matching `v*.*.*` tag.
135
+ `scripts/verify_release_artifacts.py` checks deterministic artifact
136
+ metadata/content, and
105
137
  `tests/python/test_release_metadata.py` guards release metadata drift.
106
138
 
107
139
  ## Commit & Pull Request Guidelines
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.6.0](///compare/v0.5.0...v0.6.0) (2026-07-13)
6
+
7
+
8
+ ### Features
9
+
10
+ * **manager:** retain qualified solve diagnostics c6445ec
11
+ * **model:** declare explicit runtime metadata ad41f94
12
+
5
13
  ## [0.5.0](https://github.com/SolverForge/solverforge-py/compare/v0.4.1...v0.5.0) (2026-07-03)
6
14
 
7
15
 
@@ -607,9 +607,9 @@ dependencies = [
607
607
 
608
608
  [[package]]
609
609
  name = "solverforge-bridge"
610
- version = "0.17.2"
610
+ version = "0.18.0"
611
611
  source = "registry+https://github.com/rust-lang/crates.io-index"
612
- checksum = "f1547aa9225350dcd821fa535f77c8048b13ceaf725e770f16ea3aa8e1eb4516"
612
+ checksum = "a9c592f73f90c14ca2af38b80ba6371ff4d41b6aaebafe341086225161836353"
613
613
  dependencies = [
614
614
  "solverforge-config",
615
615
  "solverforge-core",
@@ -619,9 +619,9 @@ dependencies = [
619
619
 
620
620
  [[package]]
621
621
  name = "solverforge-config"
622
- version = "0.17.2"
622
+ version = "0.18.0"
623
623
  source = "registry+https://github.com/rust-lang/crates.io-index"
624
- checksum = "8fc069e436715ac985d86e4e0ed2b0875ef2e8bf9f3db28d326d4861a4c4c1b3"
624
+ checksum = "0cb6e55b036aaff944d1c772ca6e51524c1dfe8dfa704342c2319b47665b8834"
625
625
  dependencies = [
626
626
  "serde",
627
627
  "serde_yaml",
@@ -632,9 +632,9 @@ dependencies = [
632
632
 
633
633
  [[package]]
634
634
  name = "solverforge-console"
635
- version = "0.17.2"
635
+ version = "0.18.0"
636
636
  source = "registry+https://github.com/rust-lang/crates.io-index"
637
- checksum = "17496619ea38be995def17793ad387d1fc4049a6f49a806d3b24a9accec074ee"
637
+ checksum = "e100997cd6d2fbafc8eb8e1d84bf60149a1386b89e8562a81d9408085a00520c"
638
638
  dependencies = [
639
639
  "num-format",
640
640
  "owo-colors",
@@ -644,18 +644,18 @@ dependencies = [
644
644
 
645
645
  [[package]]
646
646
  name = "solverforge-core"
647
- version = "0.17.2"
647
+ version = "0.18.0"
648
648
  source = "registry+https://github.com/rust-lang/crates.io-index"
649
- checksum = "2fd99a8ef8afe51a1958fa886a38b46e2029298b738f5a10635caa80450d72d2"
649
+ checksum = "d922c9a0ee10e0ba68c7c9b98e38d07399820358dc0d10d238a9e6641ef45d27"
650
650
  dependencies = [
651
651
  "thiserror",
652
652
  ]
653
653
 
654
654
  [[package]]
655
655
  name = "solverforge-scoring"
656
- version = "0.17.2"
656
+ version = "0.18.0"
657
657
  source = "registry+https://github.com/rust-lang/crates.io-index"
658
- checksum = "09a3c8598734bee86f3d60b9994febae8d9062a0243ae638f63417a7344cc41d"
658
+ checksum = "40a4b4eb8031ba04556106ae1bb13533c4f50ab206b3c5844c4e0284e42bd4f2"
659
659
  dependencies = [
660
660
  "solverforge-core",
661
661
  "thiserror",
@@ -663,9 +663,9 @@ dependencies = [
663
663
 
664
664
  [[package]]
665
665
  name = "solverforge-solver"
666
- version = "0.17.2"
666
+ version = "0.18.0"
667
667
  source = "registry+https://github.com/rust-lang/crates.io-index"
668
- checksum = "79b472d2acf63b5dc284bbfec4800cdd476908fe5e5c0f33141b30bf1c37d584"
668
+ checksum = "7a5b5a898495984107de03cdc9c151c39ec9b4d70cfa509950cbe58c263953a4"
669
669
  dependencies = [
670
670
  "rand",
671
671
  "rand_chacha",
@@ -691,7 +691,7 @@ dependencies = [
691
691
 
692
692
  [[package]]
693
693
  name = "solverforge_py"
694
- version = "0.5.0"
694
+ version = "0.6.0"
695
695
  dependencies = [
696
696
  "indexmap",
697
697
  "once_cell",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "solverforge_py"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  edition = "2021"
5
5
  license = "Apache-2.0"
6
6
  rust-version = "1.95"
@@ -15,7 +15,7 @@ name = "solverforge_py"
15
15
  crate-type = ["cdylib", "rlib"]
16
16
 
17
17
  [package.metadata.solverforge]
18
- version = "0.17.2"
18
+ version = "0.18.0"
19
19
 
20
20
  [dependencies]
21
21
  indexmap = "2.12.1"
@@ -31,12 +31,12 @@ toml = "0.9.8"
31
31
  tracing = "0.1.44"
32
32
  tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
33
33
 
34
- solverforge-config = { version = "=0.17.2" }
35
- solverforge-bridge = { version = "=0.17.2" }
36
- solverforge-console = { version = "=0.17.2", features = ["verbose-logging"] }
37
- solverforge-core = { version = "=0.17.2" }
38
- solverforge-scoring = { version = "=0.17.2" }
39
- solverforge-solver = { version = "=0.17.2" }
34
+ solverforge-config = { version = "=0.18.0" }
35
+ solverforge-bridge = { version = "=0.18.0" }
36
+ solverforge-console = { version = "=0.18.0", features = ["verbose-logging"] }
37
+ solverforge-core = { version = "=0.18.0" }
38
+ solverforge-scoring = { version = "=0.18.0" }
39
+ solverforge-solver = { version = "=0.18.0" }
40
40
  solverforge-ui = { version = "=0.7.0", default-features = false }
41
41
 
42
42
  [dev-dependencies]
@@ -43,7 +43,7 @@ SOLVERFORGE_RELEASE_VERSION := $(shell $(HOST_PYTHON) scripts/verify_solverforge
43
43
  MYPY_PATHS := python/solverforge examples/solverforge_hospital examples/solverforge_deliveries
44
44
  PY_STYLE_PATHS := python tests examples scripts
45
45
  DOC_CHECK_PATHS := README.md AGENTS.md WIREFRAME.md examples/solverforge_hospital/README.md examples/solverforge_deliveries/README.md
46
- DOC_STALE_PATTERNS := move_count_limit|bounded scalar assignment fallback|currently contains scaffolding|owner-aware, nearby, swap, sublist, reverse, k-opt, and ruin selectors .*not yet|no committed history yet|/home/pvd/dev/solverforge|next release from this checkout|As of 2026-07-03|Install the published package and run
46
+ DOC_STALE_PATTERNS := move_count_limit|bounded scalar assignment fallback|currently contains scaffolding|owner-aware, nearby, swap, sublist, reverse, k-opt, and ruin selectors .*not yet|no committed history yet|/home/pvd|/srv/lab/dev/solverforge|next release from this checkout|As of 2026-07-03|Install the published package and run|0\.17\.2|0\.18\.0.*not published|unpublished.*0\.18\.0|registry-backed builds remain intentionally blocked|release-base gate red|exact SolverForge.*registry dependencies are available|CVRP route callbacks|route callbacks for depot lookup|July 11, 2026|July 13, 2026|PyPI approval job|reviewed .*pypi.*environment|require manual approval|unreleased .*0\.6\.0|There is no .*v0\.6\.0 tag|PyPI latest .*0\.4\.0
47
47
  PY_DEPS_STAMP := $(VENV)/.solverforge-py-deps
48
48
  PLAYWRIGHT_BROWSERS_STAMP := $(VENV)/.solverforge-py-playwright-chromium
49
49
  PY_LIBDIR := $(shell $(HOST_PYTHON) -c 'import sysconfig; print(sysconfig.get_config_var("LIBDIR") or "")')
@@ -245,7 +245,18 @@ docs-check:
245
245
  @test ! -d docs
246
246
  @test -f examples/solverforge_hospital/README.md
247
247
  @test -f examples/solverforge_deliveries/README.md
248
- @! rg -n "$(DOC_STALE_PATTERNS)" $(DOC_CHECK_PATHS)
248
+ @! grep -En "$(DOC_STALE_PATTERNS)" $(DOC_CHECK_PATHS)
249
+ @grep -Eq '@candidate_metric' README.md
250
+ @grep -Eq 'QualifiedCandidateTraceProvenance' README.md
251
+ @grep -Eq '@candidate_metric' AGENTS.md
252
+ @grep -Eq 'QualifiedCandidateTraceProvenance' AGENTS.md
253
+ @grep -Eq '@candidate_metric' WIREFRAME.md
254
+ @grep -Eq 'QualifiedCandidateTraceProvenance' WIREFRAME.md
255
+ @grep -Eq 'list_round_robin' README.md WIREFRAME.md
256
+ @grep -Eq 'weakest_fit_decreasing' README.md WIREFRAME.md
257
+ @grep -Eq 'ui.asset_paths' README.md WIREFRAME.md
258
+ @grep -Eq 'assign_when_candidate_exists' examples/solverforge_hospital/README.md
259
+ @grep -Eq 'RowField' examples/solverforge_deliveries/README.md
249
260
  @printf -- "$(GREEN)$(CHECK) Documentation surface looks current$(RESET)\n"
250
261
 
251
262
  release-base-check: