django-due 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-due might be problematic. Click here for more details.

Files changed (358) hide show
  1. django_due-0.1.0/.github/dependabot.yml +8 -0
  2. django_due-0.1.0/.github/pull_request_template.md +9 -0
  3. django_due-0.1.0/.github/workflows/ci.yml +132 -0
  4. django_due-0.1.0/.github/workflows/pr-title.yml +32 -0
  5. django_due-0.1.0/.github/workflows/release.yaml +224 -0
  6. django_due-0.1.0/.gitignore +15 -0
  7. django_due-0.1.0/.pre-commit-config.yaml +20 -0
  8. django_due-0.1.0/.python-version +1 -0
  9. django_due-0.1.0/.release-please-manifest.json +1 -0
  10. django_due-0.1.0/CHANGELOG.md +99 -0
  11. django_due-0.1.0/CONTRIBUTING.md +75 -0
  12. django_due-0.1.0/LICENSE +202 -0
  13. django_due-0.1.0/NOTICE +5 -0
  14. django_due-0.1.0/PKG-INFO +291 -0
  15. django_due-0.1.0/README.md +260 -0
  16. django_due-0.1.0/RELEASING.md +102 -0
  17. django_due-0.1.0/compose.yaml +23 -0
  18. django_due-0.1.0/docs/alternatives.md +128 -0
  19. django_due-0.1.0/docs/architecture.md +165 -0
  20. django_due-0.1.0/docs/backend-adoption.md +134 -0
  21. django_due-0.1.0/docs/capabilities.md +96 -0
  22. django_due-0.1.0/docs/completion-leases.md +51 -0
  23. django_due-0.1.0/docs/conformance-api.md +233 -0
  24. django_due-0.1.0/docs/conformance.md +480 -0
  25. django_due-0.1.0/docs/cutover-audit.md +182 -0
  26. django_due-0.1.0/docs/demo-comparisons.md +73 -0
  27. django_due-0.1.0/docs/extraction.md +47 -0
  28. django_due-0.1.0/docs/integration.md +206 -0
  29. django_due-0.1.0/docs/investigations/backend-migration-audit-2026-10-11.md +380 -0
  30. django_due-0.1.0/docs/migrations/arq.md +311 -0
  31. django_due-0.1.0/docs/migrations/celery.md +369 -0
  32. django_due-0.1.0/docs/migrations/chancy.md +310 -0
  33. django_due-0.1.0/docs/migrations/dbos.md +334 -0
  34. django_due-0.1.0/docs/migrations/django-q2.md +299 -0
  35. django_due-0.1.0/docs/migrations/django-rq.md +303 -0
  36. django_due-0.1.0/docs/migrations/django-tasks-db.md +353 -0
  37. django_due-0.1.0/docs/migrations/django-tasks-rq.md +352 -0
  38. django_due-0.1.0/docs/migrations/django-tasks.md +459 -0
  39. django_due-0.1.0/docs/migrations/dramatiq.md +299 -0
  40. django_due-0.1.0/docs/migrations/huey.md +347 -0
  41. django_due-0.1.0/docs/migrations/pgmq.md +310 -0
  42. django_due-0.1.0/docs/migrations/pgqueuer.md +312 -0
  43. django_due-0.1.0/docs/migrations/procrastinate.md +387 -0
  44. django_due-0.1.0/docs/migrations/rq.md +374 -0
  45. django_due-0.1.0/docs/migrations/taskiq.md +307 -0
  46. django_due-0.1.0/docs/migrations/temporal.md +339 -0
  47. django_due-0.1.0/docs/migrations.md +58 -0
  48. django_due-0.1.0/docs/operations.md +130 -0
  49. django_due-0.1.0/docs/recovery-walkthrough.md +121 -0
  50. django_due-0.1.0/docs/verification.md +105 -0
  51. django_due-0.1.0/docs/why-due.md +210 -0
  52. django_due-0.1.0/docs/work-in-progress/tickets/adopter-integration-third-audit-test-plan.md +16 -0
  53. django_due-0.1.0/docs/work-in-progress/tickets/application-outcome-proofs-test-plan.md +12 -0
  54. django_due-0.1.0/docs/work-in-progress/tickets/audit-port-and-guides-test-plan.md +47 -0
  55. django_due-0.1.0/docs/work-in-progress/tickets/backend-replacement-test-plan.md +20 -0
  56. django_due-0.1.0/docs/work-in-progress/tickets/be-harness-parity-test-plan.md +20 -0
  57. django_due-0.1.0/docs/work-in-progress/tickets/books-convergence-test-plan.md +3 -0
  58. django_due-0.1.0/docs/work-in-progress/tickets/codex-due-bindings-test-plan.md +33 -0
  59. django_due-0.1.0/docs/work-in-progress/tickets/codex-due-comparison-test-plan.md +46 -0
  60. django_due-0.1.0/docs/work-in-progress/tickets/codex-initial-extraction-test-plan.md +12 -0
  61. django_due-0.1.0/docs/work-in-progress/tickets/codex-scheduled-publication-test-plan.md +49 -0
  62. django_due-0.1.0/docs/work-in-progress/tickets/proof-resource-ownership-test-plan.md +26 -0
  63. django_due-0.1.0/docs/work-in-progress/tickets/selection-completeness-parity-test-plan.md +23 -0
  64. django_due-0.1.0/docs/work-in-progress/tickets/upstream-cutover-test-plan.md +55 -0
  65. django_due-0.1.0/examples/README.md +82 -0
  66. django_due-0.1.0/examples/__init__.py +5 -0
  67. django_due-0.1.0/examples/apps.py +11 -0
  68. django_due-0.1.0/examples/books/README.md +246 -0
  69. django_due-0.1.0/examples/books/__init__.py +0 -0
  70. django_due-0.1.0/examples/books/effects.py +43 -0
  71. django_due-0.1.0/examples/books/migrations/0001_initial.py +259 -0
  72. django_due-0.1.0/examples/books/migrations/__init__.py +0 -0
  73. django_due-0.1.0/examples/books/models.py +37 -0
  74. django_due-0.1.0/examples/books/search.py +73 -0
  75. django_due-0.1.0/examples/books/services.py +28 -0
  76. django_due-0.1.0/examples/books/templates/books/form.html +9 -0
  77. django_due-0.1.0/examples/books/templates/books/list.html +25 -0
  78. django_due-0.1.0/examples/books/views.py +30 -0
  79. django_due-0.1.0/examples/catalog/README.md +38 -0
  80. django_due-0.1.0/examples/catalog/__init__.py +0 -0
  81. django_due-0.1.0/examples/catalog/effects.py +33 -0
  82. django_due-0.1.0/examples/catalog/migrations/0001_initial.py +147 -0
  83. django_due-0.1.0/examples/catalog/migrations/__init__.py +0 -0
  84. django_due-0.1.0/examples/catalog/models.py +25 -0
  85. django_due-0.1.0/examples/catalog/services.py +23 -0
  86. django_due-0.1.0/examples/celery_app.py +13 -0
  87. django_due-0.1.0/examples/celery_migration/README.md +127 -0
  88. django_due-0.1.0/examples/celery_migration/__init__.py +1 -0
  89. django_due-0.1.0/examples/celery_migration/tasks.py +37 -0
  90. django_due-0.1.0/examples/comparison/README.md +79 -0
  91. django_due-0.1.0/examples/comparison/__init__.py +0 -0
  92. django_due-0.1.0/examples/comparison/settings.py +6 -0
  93. django_due-0.1.0/examples/comparison/tasks.py +51 -0
  94. django_due-0.1.0/examples/documents/README.md +28 -0
  95. django_due-0.1.0/examples/documents/__init__.py +0 -0
  96. django_due-0.1.0/examples/documents/apps.py +6 -0
  97. django_due-0.1.0/examples/documents/effects.py +43 -0
  98. django_due-0.1.0/examples/documents/migrations/0001_initial.py +142 -0
  99. django_due-0.1.0/examples/documents/migrations/0002_document_publication_failed.py +17 -0
  100. django_due-0.1.0/examples/documents/migrations/__init__.py +0 -0
  101. django_due-0.1.0/examples/documents/models.py +20 -0
  102. django_due-0.1.0/examples/documents/storage.py +53 -0
  103. django_due-0.1.0/examples/management/__init__.py +0 -0
  104. django_due-0.1.0/examples/management/commands/__init__.py +0 -0
  105. django_due-0.1.0/examples/management/commands/catalog_entry.py +20 -0
  106. django_due-0.1.0/examples/management/commands/print_book.py +16 -0
  107. django_due-0.1.0/examples/management/commands/scheduled_publication.py +53 -0
  108. django_due-0.1.0/examples/orders/README.md +47 -0
  109. django_due-0.1.0/examples/orders/__init__.py +0 -0
  110. django_due-0.1.0/examples/orders/effects.py +41 -0
  111. django_due-0.1.0/examples/orders/migrations/0001_initial.py +172 -0
  112. django_due-0.1.0/examples/orders/migrations/__init__.py +0 -0
  113. django_due-0.1.0/examples/orders/models.py +30 -0
  114. django_due-0.1.0/examples/orders/provider.py +63 -0
  115. django_due-0.1.0/examples/orders/services.py +13 -0
  116. django_due-0.1.0/examples/registry.py +17 -0
  117. django_due-0.1.0/examples/scheduled/README.md +250 -0
  118. django_due-0.1.0/examples/scheduled/__init__.py +1 -0
  119. django_due-0.1.0/examples/scheduled/effects.py +40 -0
  120. django_due-0.1.0/examples/scheduled/forms.py +16 -0
  121. django_due-0.1.0/examples/scheduled/migrations/0001_initial.py +158 -0
  122. django_due-0.1.0/examples/scheduled/migrations/0002_submission_identity.py +41 -0
  123. django_due-0.1.0/examples/scheduled/migrations/__init__.py +0 -0
  124. django_due-0.1.0/examples/scheduled/models.py +31 -0
  125. django_due-0.1.0/examples/scheduled/services.py +77 -0
  126. django_due-0.1.0/examples/scheduled/templates/scheduled/detail.html +13 -0
  127. django_due-0.1.0/examples/scheduled/templates/scheduled/list.html +10 -0
  128. django_due-0.1.0/examples/scheduled/views.py +88 -0
  129. django_due-0.1.0/examples/settings.py +35 -0
  130. django_due-0.1.0/examples/urls.py +11 -0
  131. django_due-0.1.0/pyproject.toml +96 -0
  132. django_due-0.1.0/release-please-config.json +62 -0
  133. django_due-0.1.0/scripts/check_adoption_report.py +111 -0
  134. django_due-0.1.0/scripts/check_backend_compatibility.py +103 -0
  135. django_due-0.1.0/scripts/check_wheel.py +44 -0
  136. django_due-0.1.0/src/due/__init__.py +1 -0
  137. django_due-0.1.0/src/due/_installed.py +58 -0
  138. django_due-0.1.0/src/due/_suite_inventory.py +119 -0
  139. django_due-0.1.0/src/due/django/__init__.py +4 -0
  140. django_due-0.1.0/src/due/django/apps.py +8 -0
  141. django_due-0.1.0/src/due/django/capabilities/__init__.py +4 -0
  142. django_due-0.1.0/src/due/django/capabilities/_attempt_recovery.py +45 -0
  143. django_due-0.1.0/src/due/django/capabilities/authoring.py +1074 -0
  144. django_due-0.1.0/src/due/django/capabilities/compensation.py +153 -0
  145. django_due-0.1.0/src/due/django/capabilities/observed_operations.py +133 -0
  146. django_due-0.1.0/src/due/django/capabilities/operations.py +393 -0
  147. django_due-0.1.0/src/due/django/capabilities/projection.py +237 -0
  148. django_due-0.1.0/src/due/django/capabilities/scheduled.py +288 -0
  149. django_due-0.1.0/src/due/django/completion.py +144 -0
  150. django_due-0.1.0/src/due/django/conformance/__init__.py +21 -0
  151. django_due-0.1.0/src/due/django/conformance/_binding.py +4 -0
  152. django_due-0.1.0/src/due/django/conformance/_internal/__init__.py +1 -0
  153. django_due-0.1.0/src/due/django/conformance/_internal/immutable_inputs.py +293 -0
  154. django_due-0.1.0/src/due/django/conformance/_internal/suite.py +1477 -0
  155. django_due-0.1.0/src/due/django/conformance/background.py +550 -0
  156. django_due-0.1.0/src/due/django/conformance/background_beat.py +60 -0
  157. django_due-0.1.0/src/due/django/conformance/binding.py +4 -0
  158. django_due-0.1.0/src/due/django/conformance/bindings.py +355 -0
  159. django_due-0.1.0/src/due/django/conformance/collected_effects.py +109 -0
  160. django_due-0.1.0/src/due/django/conformance/composition.py +257 -0
  161. django_due-0.1.0/src/due/django/conformance/concurrency.py +124 -0
  162. django_due-0.1.0/src/due/django/conformance/database.py +23 -0
  163. django_due-0.1.0/src/due/django/conformance/delivery.py +150 -0
  164. django_due-0.1.0/src/due/django/conformance/discovery_admissibility.py +189 -0
  165. django_due-0.1.0/src/due/django/conformance/enrollment.py +49 -0
  166. django_due-0.1.0/src/due/django/conformance/examples.py +215 -0
  167. django_due-0.1.0/src/due/django/conformance/host.py +35 -0
  168. django_due-0.1.0/src/due/django/conformance/indexes.py +81 -0
  169. django_due-0.1.0/src/due/django/conformance/interleavings.py +114 -0
  170. django_due-0.1.0/src/due/django/conformance/observations.py +251 -0
  171. django_due-0.1.0/src/due/django/conformance/provider.py +110 -0
  172. django_due-0.1.0/src/due/django/conformance/recovery_isolation.py +309 -0
  173. django_due-0.1.0/src/due/django/conformance/registrations.py +51 -0
  174. django_due-0.1.0/src/due/django/conformance/reporting.py +145 -0
  175. django_due-0.1.0/src/due/django/conformance/scenarios.py +581 -0
  176. django_due-0.1.0/src/due/django/conformance/seams.py +425 -0
  177. django_due-0.1.0/src/due/django/conformance/suite.py +97 -0
  178. django_due-0.1.0/src/due/django/conformance/suite_collection.py +238 -0
  179. django_due-0.1.0/src/due/django/conformance/worker_connection.py +16 -0
  180. django_due-0.1.0/src/due/django/declarations/__init__.py +4 -0
  181. django_due-0.1.0/src/due/django/declarations/capture.py +70 -0
  182. django_due-0.1.0/src/due/django/declarations/dependents.py +23 -0
  183. django_due-0.1.0/src/due/django/declarations/eligibility.py +48 -0
  184. django_due-0.1.0/src/due/django/declarations/external_services.py +56 -0
  185. django_due-0.1.0/src/due/django/declarations/mirrors.py +80 -0
  186. django_due-0.1.0/src/due/django/evidence/__init__.py +4 -0
  187. django_due-0.1.0/src/due/django/evidence/attempts.py +280 -0
  188. django_due-0.1.0/src/due/django/evidence/effect_evidence.py +101 -0
  189. django_due-0.1.0/src/due/django/integration.py +72 -0
  190. django_due-0.1.0/src/due/django/management/__init__.py +0 -0
  191. django_due-0.1.0/src/due/django/management/commands/__init__.py +0 -0
  192. django_due-0.1.0/src/due/django/management/commands/due_check.py +47 -0
  193. django_due-0.1.0/src/due/django/management/commands/due_status.py +96 -0
  194. django_due-0.1.0/src/due/django/migrations/0001_initial.py +102 -0
  195. django_due-0.1.0/src/due/django/migrations/__init__.py +1 -0
  196. django_due-0.1.0/src/due/django/models.py +329 -0
  197. django_due-0.1.0/src/due/django/public.py +113 -0
  198. django_due-0.1.0/src/due/django/runtime/__init__.py +4 -0
  199. django_due-0.1.0/src/due/django/runtime/_delivery.py +163 -0
  200. django_due-0.1.0/src/due/django/runtime/coordination.py +1133 -0
  201. django_due-0.1.0/src/due/django/runtime/counters.py +22 -0
  202. django_due-0.1.0/src/due/django/runtime/diagnostics.py +67 -0
  203. django_due-0.1.0/src/due/django/runtime/limits.py +7 -0
  204. django_due-0.1.0/src/due/django/runtime/metrics.py +297 -0
  205. django_due-0.1.0/src/due/django/runtime/names.py +13 -0
  206. django_due-0.1.0/src/due/django/runtime/recovery_pass.py +546 -0
  207. django_due-0.1.0/src/due/django/runtime/registry.py +204 -0
  208. django_due-0.1.0/src/due/django/runtime/tasks.py +59 -0
  209. django_due-0.1.0/src/due/django/runtime/transport.py +56 -0
  210. django_due-0.1.0/src/due/django/testing.py +136 -0
  211. django_due-0.1.0/src/due/errors.py +77 -0
  212. django_due-0.1.0/src/due/observability.py +17 -0
  213. django_due-0.1.0/src/due/observations.py +20 -0
  214. django_due-0.1.0/src/due/py.typed +0 -0
  215. django_due-0.1.0/src/due/pytest_plugin.py +69 -0
  216. django_due-0.1.0/src/due/retry_delays.py +33 -0
  217. django_due-0.1.0/tests/__init__.py +6 -0
  218. django_due-0.1.0/tests/capabilities/__init__.py +1 -0
  219. django_due-0.1.0/tests/capabilities/test_authoring.py +356 -0
  220. django_due-0.1.0/tests/capabilities/test_authoring_nonblocking.py +47 -0
  221. django_due-0.1.0/tests/capabilities/test_capability_round_trip_budget.py +199 -0
  222. django_due-0.1.0/tests/capabilities/test_compensation.py +116 -0
  223. django_due-0.1.0/tests/capabilities/test_continuations.py +142 -0
  224. django_due-0.1.0/tests/capabilities/test_deadline_wakeups.py +147 -0
  225. django_due-0.1.0/tests/capabilities/test_dependent_wake.py +371 -0
  226. django_due-0.1.0/tests/capabilities/test_eligibility.py +258 -0
  227. django_due-0.1.0/tests/capabilities/test_eligibility_evidence.py +104 -0
  228. django_due-0.1.0/tests/capabilities/test_input_fields.py +108 -0
  229. django_due-0.1.0/tests/capabilities/test_observation_recovery.py +284 -0
  230. django_due-0.1.0/tests/capabilities/test_observation_smoke.py +106 -0
  231. django_due-0.1.0/tests/capabilities/test_observations.py +61 -0
  232. django_due-0.1.0/tests/capabilities/test_operation_observed_evidence.py +84 -0
  233. django_due-0.1.0/tests/capabilities/test_operation_recovery_isolation.py +109 -0
  234. django_due-0.1.0/tests/capabilities/test_operation_rejection_evidence.py +254 -0
  235. django_due-0.1.0/tests/capabilities/test_provider_calls.py +66 -0
  236. django_due-0.1.0/tests/capabilities/test_recover_dispatch_clock.py +94 -0
  237. django_due-0.1.0/tests/capabilities/test_recovery_deferral.py +497 -0
  238. django_due-0.1.0/tests/capabilities/test_required_completion.py +304 -0
  239. django_due-0.1.0/tests/capabilities/test_scheduled_action_schedule_at.py +110 -0
  240. django_due-0.1.0/tests/comparison/__init__.py +0 -0
  241. django_due-0.1.0/tests/comparison/test_books.py +102 -0
  242. django_due-0.1.0/tests/conformance/__init__.py +1 -0
  243. django_due-0.1.0/tests/conformance/bindings.py +136 -0
  244. django_due-0.1.0/tests/conformance/book_examples.py +234 -0
  245. django_due-0.1.0/tests/conformance/catalog_examples.py +97 -0
  246. django_due-0.1.0/tests/conformance/conftest.py +41 -0
  247. django_due-0.1.0/tests/conformance/debt_baseline.yaml +14 -0
  248. django_due-0.1.0/tests/conformance/document_examples.py +147 -0
  249. django_due-0.1.0/tests/conformance/index_examples.py +22 -0
  250. django_due-0.1.0/tests/conformance/order_examples.py +146 -0
  251. django_due-0.1.0/tests/conformance/scheduled_examples.py +172 -0
  252. django_due-0.1.0/tests/conformance/test_application_binding_scopes.py +68 -0
  253. django_due-0.1.0/tests/conformance/test_background_transport.py +74 -0
  254. django_due-0.1.0/tests/conformance/test_background_work_failure_accounting.py +398 -0
  255. django_due-0.1.0/tests/conformance/test_background_work_frozen_clock_skew.py +33 -0
  256. django_due-0.1.0/tests/conformance/test_background_work_provider_acceptance.py +43 -0
  257. django_due-0.1.0/tests/conformance/test_book_contracts.py +13 -0
  258. django_due-0.1.0/tests/conformance/test_books_contract_controls.py +72 -0
  259. django_due-0.1.0/tests/conformance/test_catalog_contract.py +8 -0
  260. django_due-0.1.0/tests/conformance/test_ci_evidence.py +120 -0
  261. django_due-0.1.0/tests/conformance/test_classified_failures.py +134 -0
  262. django_due-0.1.0/tests/conformance/test_concurrent_delivery.py +362 -0
  263. django_due-0.1.0/tests/conformance/test_conformance_collection_declared_scenarios.py +138 -0
  264. django_due-0.1.0/tests/conformance/test_conformance_collection_missing_proofs.py +172 -0
  265. django_due-0.1.0/tests/conformance/test_conformance_collection_outcomes.py +119 -0
  266. django_due-0.1.0/tests/conformance/test_conformance_collection_reports.py +314 -0
  267. django_due-0.1.0/tests/conformance/test_conformance_enrollment.py +743 -0
  268. django_due-0.1.0/tests/conformance/test_contract.py +53 -0
  269. django_due-0.1.0/tests/conformance/test_database_proof_controls.py +411 -0
  270. django_due-0.1.0/tests/conformance/test_discovery_admissibility.py +125 -0
  271. django_due-0.1.0/tests/conformance/test_discovery_completeness.py +51 -0
  272. django_due-0.1.0/tests/conformance/test_document_contract.py +10 -0
  273. django_due-0.1.0/tests/conformance/test_document_process_control.py +22 -0
  274. django_due-0.1.0/tests/conformance/test_evidence_proofs_require_due_work.py +34 -0
  275. django_due-0.1.0/tests/conformance/test_failing_external_call.py +21 -0
  276. django_due-0.1.0/tests/conformance/test_host.py +62 -0
  277. django_due-0.1.0/tests/conformance/test_immutable_inputs_claim.py +254 -0
  278. django_due-0.1.0/tests/conformance/test_lock_order_recorder.py +64 -0
  279. django_due-0.1.0/tests/conformance/test_nested_project_inventory.py +24 -0
  280. django_due-0.1.0/tests/conformance/test_observation_contract.py +159 -0
  281. django_due-0.1.0/tests/conformance/test_operation_uncertainty.py +58 -0
  282. django_due-0.1.0/tests/conformance/test_order_contract.py +8 -0
  283. django_due-0.1.0/tests/conformance/test_persistent_retry.py +60 -0
  284. django_due-0.1.0/tests/conformance/test_process_outcomes.py +32 -0
  285. django_due-0.1.0/tests/conformance/test_provider_probe.py +172 -0
  286. django_due-0.1.0/tests/conformance/test_provider_seam.py +227 -0
  287. django_due-0.1.0/tests/conformance/test_query_scale.py +292 -0
  288. django_due-0.1.0/tests/conformance/test_recovery_isolation_phase_proofs.py +27 -0
  289. django_due-0.1.0/tests/conformance/test_registration_scopes.py +33 -0
  290. django_due-0.1.0/tests/conformance/test_scheduled_contract.py +8 -0
  291. django_due-0.1.0/tests/conformance/test_scheduler_adapters.py +176 -0
  292. django_due-0.1.0/tests/conformance/test_synchronous_caller_scenario.py +126 -0
  293. django_due-0.1.0/tests/conformance/test_terminal_example.py +71 -0
  294. django_due-0.1.0/tests/declarations/__init__.py +1 -0
  295. django_due-0.1.0/tests/declarations/test_declarations.py +332 -0
  296. django_due-0.1.0/tests/declarations/test_mirror_receipts.py +116 -0
  297. django_due-0.1.0/tests/declarations/test_simple_callbacks.py +160 -0
  298. django_due-0.1.0/tests/evidence/__init__.py +1 -0
  299. django_due-0.1.0/tests/evidence/test_canonical_receipt_storage.py +99 -0
  300. django_due-0.1.0/tests/evidence/test_evidence_histories.py +442 -0
  301. django_due-0.1.0/tests/examples/__init__.py +0 -0
  302. django_due-0.1.0/tests/examples/books_support.py +41 -0
  303. django_due-0.1.0/tests/examples/file_support.py +37 -0
  304. django_due-0.1.0/tests/examples/test_books.py +77 -0
  305. django_due-0.1.0/tests/examples/test_catalog.py +41 -0
  306. django_due-0.1.0/tests/examples/test_celery_migration.py +99 -0
  307. django_due-0.1.0/tests/examples/test_orders.py +48 -0
  308. django_due-0.1.0/tests/examples/test_revision_storage.py +148 -0
  309. django_due-0.1.0/tests/examples/test_scheduled.py +146 -0
  310. django_due-0.1.0/tests/examples/test_scheduled_migration.py +29 -0
  311. django_due-0.1.0/tests/examples/test_startup.py +47 -0
  312. django_due-0.1.0/tests/examples/test_submission_keys.py +123 -0
  313. django_due-0.1.0/tests/harness/__init__.py +6 -0
  314. django_due-0.1.0/tests/harness/book_process.py +45 -0
  315. django_due-0.1.0/tests/harness/broker.py +42 -0
  316. django_due-0.1.0/tests/harness/collection_sessions.py +293 -0
  317. django_due-0.1.0/tests/harness/comparison_process.py +46 -0
  318. django_due-0.1.0/tests/harness/dependents.py +118 -0
  319. django_due-0.1.0/tests/harness/document_process.py +33 -0
  320. django_due-0.1.0/tests/harness/enrollment.py +118 -0
  321. django_due-0.1.0/tests/harness/evidence.py +40 -0
  322. django_due-0.1.0/tests/harness/gated.py +13 -0
  323. django_due-0.1.0/tests/harness/observation.py +106 -0
  324. django_due-0.1.0/tests/harness/operation.py +97 -0
  325. django_due-0.1.0/tests/harness/primitive.py +147 -0
  326. django_due-0.1.0/tests/harness/processes.py +32 -0
  327. django_due-0.1.0/tests/harness/registrations.py +5 -0
  328. django_due-0.1.0/tests/harness/scheduled_process.py +44 -0
  329. django_due-0.1.0/tests/integration/processes.py +39 -0
  330. django_due-0.1.0/tests/integration/test_books_live.py +100 -0
  331. django_due-0.1.0/tests/integration/test_books_worker.py +45 -0
  332. django_due-0.1.0/tests/integration/test_celery_migration.py +30 -0
  333. django_due-0.1.0/tests/integration/test_celery_worker.py +41 -0
  334. django_due-0.1.0/tests/integration/test_richer_examples.py +57 -0
  335. django_due-0.1.0/tests/integration/test_scheduled_live.py +90 -0
  336. django_due-0.1.0/tests/integration/worker.py +76 -0
  337. django_due-0.1.0/tests/runtime/__init__.py +1 -0
  338. django_due-0.1.0/tests/runtime/test_check_command.py +75 -0
  339. django_due-0.1.0/tests/runtime/test_delivery_budget.py +116 -0
  340. django_due-0.1.0/tests/runtime/test_deployment_contracts.py +77 -0
  341. django_due-0.1.0/tests/runtime/test_execution.py +269 -0
  342. django_due-0.1.0/tests/runtime/test_lock_owner_of_work.py +77 -0
  343. django_due-0.1.0/tests/runtime/test_metric_failures.py +51 -0
  344. django_due-0.1.0/tests/runtime/test_private_delivery_lease.py +94 -0
  345. django_due-0.1.0/tests/runtime/test_private_delivery_page.py +78 -0
  346. django_due-0.1.0/tests/runtime/test_recovery_pass.py +292 -0
  347. django_due-0.1.0/tests/runtime/test_registry.py +174 -0
  348. django_due-0.1.0/tests/runtime/test_retry_policy.py +154 -0
  349. django_due-0.1.0/tests/runtime/test_setup.py +80 -0
  350. django_due-0.1.0/tests/runtime/test_status_command.py +69 -0
  351. django_due-0.1.0/tests/runtime/test_transport.py +134 -0
  352. django_due-0.1.0/tests/settings.py +7 -0
  353. django_due-0.1.0/tests/test_completion_lease.py +242 -0
  354. django_due-0.1.0/tests/test_completion_lease_histories.py +195 -0
  355. django_due-0.1.0/tests/test_primitive_independence.py +163 -0
  356. django_due-0.1.0/tests/test_provider_idempotency_key.py +32 -0
  357. django_due-0.1.0/tests/test_testing.py +126 -0
  358. django_due-0.1.0/uv.lock +1114 -0
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: monthly
7
+ commit-message:
8
+ prefix: ci
@@ -0,0 +1,9 @@
1
+ ## Behavior
2
+
3
+ Describe the concrete problem and resulting behavior, including the relevant
4
+ failure or recovery history.
5
+
6
+ ## Validation
7
+
8
+ Name the checks run and the limits of what they prove. For an obligation-contract
9
+ change, include the profile report and any newly unassessed guarantees.
@@ -0,0 +1,132 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ permissions:
7
+ contents: read
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v7
17
+ - uses: astral-sh/setup-uv@v7
18
+ with:
19
+ enable-cache: true
20
+ - run: uv sync --locked --only-group lint
21
+ - run: uv run --no-sync ruff check .
22
+ - run: uv run --no-sync ruff format --check .
23
+ - run: uv run --no-sync pre-commit validate-config
24
+ - name: Validate GitHub Actions
25
+ run: docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:1.7.7 -color
26
+
27
+ typecheck:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v7
31
+ - uses: astral-sh/setup-uv@v7
32
+ with:
33
+ enable-cache: true
34
+ - run: uv sync --locked
35
+ - run: uv run --no-sync pyrefly check
36
+
37
+ tests:
38
+ runs-on: ubuntu-latest
39
+ timeout-minutes: 10
40
+ strategy:
41
+ fail-fast: false
42
+ matrix:
43
+ django: [locked, minimum]
44
+ services:
45
+ postgres:
46
+ image: postgres:17
47
+ env:
48
+ POSTGRES_USER: due
49
+ POSTGRES_PASSWORD: due
50
+ POSTGRES_DB: due
51
+ ports: ["5432:5432"]
52
+ options: >-
53
+ --health-cmd "pg_isready -U due"
54
+ --health-interval 5s
55
+ --health-timeout 5s
56
+ --health-retries 10
57
+ redis:
58
+ image: redis:7
59
+ ports: ["6379:6379"]
60
+ options: >-
61
+ --health-cmd "redis-cli ping"
62
+ --health-interval 5s
63
+ --health-timeout 5s
64
+ --health-retries 10
65
+ env:
66
+ DUE_DATABASE_URL: postgresql://due:due@localhost:5432/due
67
+ DUE_BROKER_URL: redis://localhost:6379/0
68
+ steps:
69
+ - uses: actions/checkout@v7
70
+ - uses: astral-sh/setup-uv@v7
71
+ with:
72
+ enable-cache: true
73
+ - run: uv sync --locked
74
+ - name: Exercise the declared Django lower bound
75
+ if: matrix.django == 'minimum'
76
+ run: uv pip install 'django==6.0.8'
77
+ - name: Run full suite including live web, worker and Beat recovery
78
+ run: uv run --no-sync pytest --due-work-check-fixtures --basetemp=test-results -p due.django.conformance.reporting --due-work-debt-baseline=tests/conformance/debt_baseline.yaml --due-work-profile-report=profiles.json --durable-work-report=effects.json --durable-observation-report=observations.json
79
+ - name: Require executed obligation guarantees
80
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract "Due replay-safe work table" --verified A B D I J
81
+ - name: Require complete application conformance
82
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract publish_document --verified A B D E H I J --effect-report effects.json --effect publish_document --required-effect-case "test_due_work_contract[process-document process death-assert_process_deaths_converge]"
83
+ - name: Require complete book indexing conformance
84
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract index_book --verified A B D H I J --effect-report effects.json --effect index_book --required-effect-case "test_immutable_inputs_hold[admission-create book]" --required-effect-case "test_immutable_inputs_hold[admission_failure-create book]" --required-effect-case "test_due_work_contract[process-book indexing and publication process death-assert_process_deaths_converge]"
85
+ - name: Require complete book publication conformance
86
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract publish_book --verified A B D H J --effect-report effects.json --effect publish_book --required-effect-case "test_immutable_inputs_hold[producer-index settlement]"
87
+ - name: Require catalog projection conformance
88
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract project_catalog --verified A B D E H I J --effect-report effects.json --effect project_catalog
89
+ # Non-repeatable orders decline harmless replay and retain evidence indefinitely.
90
+ - name: Require observed print-order conformance
91
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract print_order --verified A B C I J --effect-report effects.json --effect print_order
92
+ - name: Require scheduled publication conformance
93
+ run: uv run --no-sync python scripts/check_adoption_report.py profiles.json --contract publish_at_deadline --verified A B E H I J --effect-report effects.json --effect publish_at_deadline --required-effect-case "test_due_work_contract[process-scheduled publication process death-assert_process_deaths_converge]"
94
+ - name: Validate application setup
95
+ run: uv run --no-sync python -m django due_check
96
+ env:
97
+ DJANGO_SETTINGS_MODULE: examples.settings
98
+ - run: uv run --no-sync python -m django makemigrations --check --dry-run
99
+ env:
100
+ DJANGO_SETTINGS_MODULE: examples.settings
101
+ - uses: actions/upload-artifact@v7
102
+ if: always()
103
+ with:
104
+ name: obligation-profiles-${{ matrix.django }}
105
+ path: |
106
+ profiles.json
107
+ effects.json
108
+ observations.json
109
+ test-results/**/*.log
110
+ if-no-files-found: error
111
+
112
+ build:
113
+ runs-on: ubuntu-latest
114
+ steps:
115
+ - uses: actions/checkout@v7
116
+ with:
117
+ fetch-depth: 0
118
+ - uses: astral-sh/setup-uv@v7
119
+ with:
120
+ enable-cache: true
121
+ - run: uv build
122
+ - run: uvx --from twine twine check --strict dist/*
123
+ - name: Install the wheel without development dependencies
124
+ run: |
125
+ uv venv /tmp/due-wheel
126
+ uv pip install --python /tmp/due-wheel dist/*.whl
127
+ /tmp/due-wheel/bin/python -I scripts/check_wheel.py
128
+ - uses: actions/upload-artifact@v7
129
+ with:
130
+ name: distributions
131
+ path: dist/
132
+ if-no-files-found: error
@@ -0,0 +1,32 @@
1
+ name: PR title
2
+
3
+ # Conventional titles keep the public change history readable.
4
+
5
+ on:
6
+ pull_request_target:
7
+ types: [opened, edited, synchronize, reopened]
8
+
9
+ permissions:
10
+ pull-requests: read
11
+
12
+ jobs:
13
+ conventional-commit:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ # Reads only the title through the API; it never checks out the pull request's code.
17
+ - uses: amannn/action-semantic-pull-request@v6
18
+ env:
19
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20
+ with:
21
+ types: |
22
+ feat
23
+ fix
24
+ perf
25
+ revert
26
+ docs
27
+ refactor
28
+ test
29
+ build
30
+ ci
31
+ chore
32
+ requireScope: false
@@ -0,0 +1,224 @@
1
+ name: Release
2
+
3
+ # After normal CI succeeds on main, release-please updates a release PR holding the next
4
+ # SemVer version and changelog, derived from Conventional Commit messages.
5
+ # Merging that PR tags vX.Y.Z and creates the GitHub release; this workflow
6
+ # then builds that exact tag and publishes it to PyPI with Trusted Publishing
7
+ # (OIDC, no stored token). See RELEASING.md.
8
+ #
9
+ # workflow_dispatch publishes an existing tag to TestPyPI or PyPI (a rehearsal,
10
+ # or a publish that failed after tagging), or, with no tag and TestPyPI, the
11
+ # dispatched commit's .devN version, which PyPI never receives.
12
+
13
+ on:
14
+ workflow_run:
15
+ workflows: [CI]
16
+ branches: [main]
17
+ types: [completed]
18
+ workflow_dispatch:
19
+ inputs:
20
+ tag:
21
+ description: "Release tag to publish, for example v0.1.0. Empty with testpypi: publish this commit's dev version"
22
+ required: false
23
+ default: ""
24
+ index:
25
+ description: "Where to publish"
26
+ type: choice
27
+ options: [testpypi, pypi]
28
+ default: testpypi
29
+
30
+ permissions: {}
31
+
32
+ concurrency:
33
+ group: release
34
+ cancel-in-progress: false
35
+
36
+ jobs:
37
+ release-please:
38
+ if: >-
39
+ github.event_name == 'workflow_run'
40
+ && github.event.workflow_run.event == 'push'
41
+ && github.event.workflow_run.conclusion == 'success'
42
+ && github.event.workflow_run.head_repository.full_name == github.repository
43
+ environment: release-automation
44
+ runs-on: ubuntu-latest
45
+ permissions:
46
+ contents: write
47
+ pull-requests: write
48
+ outputs:
49
+ release_created: ${{ steps.release.outputs.release_created }}
50
+ tag_name: ${{ steps.release.outputs.tag_name }}
51
+ steps:
52
+ - name: Only release the tested main head
53
+ id: current
54
+ uses: actions/github-script@v8
55
+ with:
56
+ script: |
57
+ const {data: branch} = await github.rest.repos.getBranch({...context.repo, branch: 'main'});
58
+ core.setOutput('matches', branch.commit.sha === context.payload.workflow_run.head_sha);
59
+ - name: Require release PR authentication
60
+ env:
61
+ HAS_RELEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN != '' }}
62
+ run: |
63
+ if [[ "$HAS_RELEASE_TOKEN" != "true" ]]; then
64
+ echo "::error::Configure RELEASE_PLEASE_TOKEN in the main-only release-automation environment."
65
+ exit 1
66
+ fi
67
+ - id: release
68
+ if: steps.current.outputs.matches == 'true'
69
+ uses: googleapis/release-please-action@v4
70
+ with:
71
+ # A non-GITHUB_TOKEN credential triggers ordinary PR CI. The main-only
72
+ # environment keeps it unavailable to pull-request test jobs.
73
+ token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
74
+ target-branch: main
75
+ config-file: release-please-config.json
76
+ manifest-file: .release-please-manifest.json
77
+
78
+ build:
79
+ needs: release-please
80
+ if: >-
81
+ always() && (
82
+ (github.event_name == 'workflow_run' && needs.release-please.result == 'success' && needs.release-please.outputs.release_created == 'true')
83
+ || github.event_name == 'workflow_dispatch'
84
+ )
85
+ runs-on: ubuntu-latest
86
+ permissions:
87
+ contents: read
88
+ actions: read
89
+ outputs:
90
+ tag: ${{ steps.tag.outputs.tag }}
91
+ version: ${{ steps.built.outputs.version }}
92
+ steps:
93
+ - id: tag
94
+ env:
95
+ TAG: ${{ needs.release-please.outputs.tag_name || inputs.tag }}
96
+ INDEX: ${{ inputs.index || 'pypi' }}
97
+ run: |
98
+ if [[ -z "$TAG" ]]; then
99
+ # Only a TestPyPI rehearsal may publish an untagged commit, as its .devN version.
100
+ if [[ "$INDEX" != "testpypi" ]]; then
101
+ echo "::error::publishing to PyPI needs a release tag" >&2
102
+ exit 1
103
+ fi
104
+ echo "tag=" >> "$GITHUB_OUTPUT"
105
+ exit 0
106
+ fi
107
+ # A release is a plain SemVer core version: vMAJOR.MINOR.PATCH.
108
+ if [[ ! "$TAG" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
109
+ echo "::error::'$TAG' is not a release tag of the form vMAJOR.MINOR.PATCH" >&2
110
+ exit 1
111
+ fi
112
+ echo "tag=$TAG" >> "$GITHUB_OUTPUT"
113
+ echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
114
+ - uses: actions/checkout@v7
115
+ with:
116
+ ref: ${{ steps.tag.outputs.tag || github.sha }}
117
+ # The version is read from the tag, so the tag must be present.
118
+ fetch-depth: 0
119
+ # Check the resolved tag, including on manual retries: a green run for a
120
+ # different commit (or a PR) must never authorize a production release.
121
+ - name: Require normal CI on the exact release commit
122
+ if: inputs.index != 'testpypi'
123
+ env:
124
+ GH_TOKEN: ${{ github.token }}
125
+ run: |
126
+ source_sha=$(git rev-parse HEAD)
127
+ count=$(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/ci.yml/runs?branch=main&event=push&status=success&head_sha=$source_sha" --jq '.total_count')
128
+ if [[ "$count" -lt 1 ]]; then
129
+ echo "::error::No successful main CI run for release commit $source_sha. Re-run its CI before publishing."
130
+ exit 1
131
+ fi
132
+ - uses: astral-sh/setup-uv@v7
133
+ - run: uv build
134
+ - run: uvx --from twine twine check --strict dist/*
135
+ - name: The built version is the tag
136
+ if: steps.tag.outputs.tag != ''
137
+ env:
138
+ VERSION: ${{ steps.tag.outputs.version }}
139
+ run: |
140
+ ls dist
141
+ test -f "dist/django_due-${VERSION}-py3-none-any.whl"
142
+ test -f "dist/django_due-${VERSION}.tar.gz"
143
+ - name: An untagged build is a dev release
144
+ if: steps.tag.outputs.tag == ''
145
+ run: |
146
+ ls dist
147
+ wheel=$(basename dist/*.whl)
148
+ [[ "$wheel" =~ ^django_due-[0-9]+\.[0-9]+(\.[0-9]+)?\.dev[0-9]+-py3-none-any\.whl$ ]]
149
+ - id: built
150
+ run: |
151
+ wheel=$(basename dist/*.whl)
152
+ version=${wheel#django_due-}
153
+ echo "version=${version%-py3-none-any.whl}" >> "$GITHUB_OUTPUT"
154
+ - name: Install the wheel without development dependencies
155
+ run: |
156
+ uv venv /tmp/wheel && uv pip install --python /tmp/wheel dist/*.whl
157
+ /tmp/wheel/bin/python -I scripts/check_wheel.py
158
+ - name: Require the testing extra to resolve from published packages
159
+ # Development CI uses the reviewed Git source. A release must also be
160
+ # installable by ordinary PyPI consumers, without uv.sources or Git.
161
+ run: |
162
+ wheel=(dist/*.whl)
163
+ uv pip install --no-sources --default-index https://pypi.org/simple --python /tmp/wheel "${wheel[0]}[testing]"
164
+ uv pip check --python /tmp/wheel
165
+ - uses: actions/upload-artifact@v7
166
+ with:
167
+ name: dist
168
+ path: dist/
169
+ if-no-files-found: error
170
+
171
+ publish-pypi:
172
+ needs: build
173
+ if: >-
174
+ always() && needs.build.result == 'success'
175
+ && (github.event_name == 'workflow_run' || inputs.index == 'pypi')
176
+ runs-on: ubuntu-latest
177
+ environment:
178
+ name: pypi
179
+ url: https://pypi.org/project/django-due/${{ needs.build.outputs.version }}/
180
+ permissions:
181
+ id-token: write
182
+ steps:
183
+ - uses: actions/download-artifact@v8
184
+ with:
185
+ name: dist
186
+ path: dist/
187
+ - uses: pypa/gh-action-pypi-publish@release/v1
188
+
189
+ publish-testpypi:
190
+ needs: build
191
+ if: >-
192
+ always() && needs.build.result == 'success'
193
+ && github.event_name == 'workflow_dispatch' && inputs.index == 'testpypi'
194
+ runs-on: ubuntu-latest
195
+ environment:
196
+ name: testpypi
197
+ url: https://test.pypi.org/project/django-due/${{ needs.build.outputs.version }}/
198
+ permissions:
199
+ id-token: write
200
+ steps:
201
+ - uses: actions/download-artifact@v8
202
+ with:
203
+ name: dist
204
+ path: dist/
205
+ - uses: pypa/gh-action-pypi-publish@release/v1
206
+ with:
207
+ repository-url: https://test.pypi.org/legacy/
208
+
209
+ attach-to-release:
210
+ needs: [build, publish-pypi]
211
+ if: always() && needs.publish-pypi.result == 'success' && needs.build.outputs.tag != ''
212
+ runs-on: ubuntu-latest
213
+ permissions:
214
+ contents: write
215
+ steps:
216
+ - uses: actions/download-artifact@v8
217
+ with:
218
+ name: dist
219
+ path: dist/
220
+ - env:
221
+ GH_TOKEN: ${{ github.token }}
222
+ TAG: ${{ needs.build.outputs.tag }}
223
+ run: gh release upload "$TAG" dist/* --clobber --repo "$GITHUB_REPOSITORY"
224
+
@@ -0,0 +1,15 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ *.egg-info/
8
+ .env
9
+
10
+ profiles.json
11
+ celerybeat-schedule*
12
+
13
+ effects.json
14
+ observations.json
15
+ test-results/
@@ -0,0 +1,20 @@
1
+ minimum_pre_commit_version: '4.3.0'
2
+ repos:
3
+ - repo: local
4
+ hooks:
5
+ - id: ruff-check
6
+ name: Ruff lint (uv.lock)
7
+ entry: uv run --locked ruff check --fix
8
+ language: system
9
+ types_or: [python, pyi]
10
+ - id: ruff-format
11
+ name: Ruff format (uv.lock)
12
+ entry: uv run --locked ruff format
13
+ language: system
14
+ types_or: [python, pyi, markdown]
15
+ - id: pyrefly
16
+ name: Pyrefly project check (uv.lock)
17
+ entry: uv run --locked pyrefly check
18
+ language: system
19
+ pass_filenames: false
20
+ files: '(^pyproject\.toml$|^uv\.lock$|\.pyi?$)'
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1 @@
1
+ {".":"0.1.0"}
@@ -0,0 +1,99 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-10-12)
4
+
5
+
6
+ ### Features
7
+
8
+ * add a runnable books example with recovery proofs ([57b94db](https://github.com/gigaverse-app/due/commit/57b94dbc98fda1d95745d63d81b7408cdb940ee3))
9
+ * add books indexing demo and recoverable handoff proofs ([dd941a3](https://github.com/gigaverse-app/due/commit/dd941a317638938e424e823e07a5bee74841ee37))
10
+ * add comparative recovery demos and setup diagnostics ([20adee4](https://github.com/gigaverse-app/due/commit/20adee48526f247690dc7e088434e68f3a09f6ed))
11
+ * add executable Celery comparison and pin Books port reference ([3d62279](https://github.com/gigaverse-app/due/commit/3d6227905e20554b851ed8bdaab09b9fffdaf810))
12
+ * add executable migration demo comparisons ([5e2aba9](https://github.com/gigaverse-app/due/commit/5e2aba9cf79d9481b4327e099b2fbb11634edf1c))
13
+ * add scheduled publication with deadline hints and submission keys ([5795f0c](https://github.com/gigaverse-app/due/commit/5795f0c5db8c49618ddb806ec189d64e17a19140))
14
+ * complete backend harness adapters and proof controls ([141af43](https://github.com/gigaverse-app/due/commit/141af432f6cd1a2203c9d9ead0caa518274edf47))
15
+ * complete discovery proofs and provider seam bindings ([87e7b12](https://github.com/gigaverse-app/due/commit/87e7b120396796c0733e411fdf503797c3a90d3a))
16
+ * complete work-table tooling and contributor workflow ([aa5fbfc](https://github.com/gigaverse-app/due/commit/aa5fbfcd8aac919696430e94915a2643f78fbb14))
17
+ * demonstrate and compare application recovery guarantees ([0a19778](https://github.com/gigaverse-app/due/commit/0a19778975824c735a784b60ad204468b388a39b))
18
+ * demonstrate scheduled publication with cancellation and recovery proofs ([0a3e38a](https://github.com/gigaverse-app/due/commit/0a3e38a91f93b72e89a8aa00d174fe52852a65a6))
19
+ * every work table can declare its provider outcome matrix ([#27](https://github.com/gigaverse-app/due/issues/27)) ([5ee2b7b](https://github.com/gigaverse-app/due/commit/5ee2b7b1d3d6d9f49f4bf21cbe965e3f603b17a2))
20
+ * extract Django work-table execution and recovery into Due ([a1e30be](https://github.com/gigaverse-app/due/commit/a1e30bec92dd03fd382ded0a6ad799b87c320914))
21
+ * finish Beat and interleaving harness adapters ([ed3de62](https://github.com/gigaverse-app/due/commit/ed3de62ea03b8755cd53c913652b75a5d57eb9f9))
22
+ * integrate adopter proofs and recover lifecycle tooling ([1204181](https://github.com/gigaverse-app/due/commit/1204181e06018dc5778bf146444824595ed6f5ec))
23
+ * port application-bound work-table conformance harness ([65e0bcf](https://github.com/gigaverse-app/due/commit/65e0bcfe426c9e663aec4ae5c71398965dde3269))
24
+ * port application-bound work-table conformance harness ([d682f93](https://github.com/gigaverse-app/due/commit/d682f93cd8c1862f0f5b49e2e6cca9957db2f742))
25
+ * preserve application fatal recovery errors and bind host proofs ([96d7ab2](https://github.com/gigaverse-app/due/commit/96d7ab2427076a810ff687766ac88e725c579064))
26
+ * preserve application recovery failures and document proof integration ([ab8ff31](https://github.com/gigaverse-app/due/commit/ab8ff31104fa2e42a997a3637e04982665789a13))
27
+ * preserve backend handoff recovery and harness mutation controls ([43b88af](https://github.com/gigaverse-app/due/commit/43b88af5f92ab324f9e49c576eb3599c8bb53e32))
28
+ * preserve deployment contracts and stronger work-table bindings ([a241d70](https://github.com/gigaverse-app/due/commit/a241d70e5e3110ee3c78e389d415b76e838f33ed))
29
+ * preserve discovery completeness and failed recovery evidence ([65d4a86](https://github.com/gigaverse-app/due/commit/65d4a8688fc78b4ec7d83b1f66c63ce9b9fb9c4f))
30
+ * prove application outcomes and publish immutable files without replay writes ([92bfacd](https://github.com/gigaverse-app/due/commit/92bfacdb2f23b1b1959e40ae02364fef9103edee))
31
+ * prove books input stability and require demo replay outcomes ([b19425e](https://github.com/gigaverse-app/due/commit/b19425eeda04c2a090e300faab733269caafcd53))
32
+ * prove immutable input claims against admission and recovery ([ac847ca](https://github.com/gigaverse-app/due/commit/ac847ca05ef3bf7afbe2f3c54c684e5014ce7de6))
33
+ * publish django-due through manually approved releases ([#26](https://github.com/gigaverse-app/due/issues/26)) ([bdcb1e6](https://github.com/gigaverse-app/due/commit/bdcb1e657861412bf85b8ed56dec393b4454b230))
34
+ * restore work-table operator tooling and harden contributor checks ([2766c33](https://github.com/gigaverse-app/due/commit/2766c33f2456886bba0f9b6c29b17018dcd2178f))
35
+ * share typed provider probes and complete Celery setup ([6765a0a](https://github.com/gigaverse-app/due/commit/6765a0ab7f079d5fe2543e26bb9915848f7a43b2))
36
+ * simplify runtime and provider bindings ([d1ebe81](https://github.com/gigaverse-app/due/commit/d1ebe81bb815ccdd96070c84d17fb8db5718143b))
37
+ * unbounded work tables claim profile J through the persistent-failure proof ([d6c8a4b](https://github.com/gigaverse-app/due/commit/d6c8a4b9ddfb3215560b938c3dcd49dd7759a088))
38
+ * unbounded work tables claim profile J through the persistent-failure proof ([c642482](https://github.com/gigaverse-app/due/commit/c642482a7853dd130719382f3cb16f01c21b84ed))
39
+ * upstream native lifecycle and cutover integration improvements ([93ca10c](https://github.com/gigaverse-app/due/commit/93ca10cb8ae11a93e1e13b21f78e7a9a0e64ce4e))
40
+ * verify immutable input claims through production admission ([533530e](https://github.com/gigaverse-app/due/commit/533530e7377d3d32e749caaef387a38a6dcf919f))
41
+ * wake near deadlines without SQL hints and deduplicate submissions ([eaa043f](https://github.com/gigaverse-app/due/commit/eaa043f5140b531f044212065bcc596c59d5bb1d))
42
+
43
+
44
+ ### Bug fixes
45
+
46
+ * consume queued recovery in the comparison harness ([9a3003e](https://github.com/gigaverse-app/due/commit/9a3003e07389f1cdbd8b53bea1cebca84f100ad7))
47
+ * failing_external_call counts every provider entry ([f4c8202](https://github.com/gigaverse-app/due/commit/f4c820257a7211ca53d1ce2e65f4812dcb8ddf05))
48
+ * initialize the example Celery app in Django processes ([5baa593](https://github.com/gigaverse-app/due/commit/5baa5938bf8c731bfe808ba8fc6ba1dbd5721c95))
49
+ * keep gate recovery on the harness-owned broker ([286e694](https://github.com/gigaverse-app/due/commit/286e6943afbc1efce1fb1e35c49fdf17f3deb400))
50
+ * preserve delivery verdicts and consolidate recovery ownership ([810c0c0](https://github.com/gigaverse-app/due/commit/810c0c0e9591e04aa853f69e5d52f512e47fd586))
51
+ * preserve proof failures through adopter cleanup ([b862931](https://github.com/gigaverse-app/due/commit/b8629317003551c78c518ba899a721752d152497))
52
+ * register deadline recovery proof and validate final harness candidate ([424a446](https://github.com/gigaverse-app/due/commit/424a44635c2ffacf01e499d4d6c710fdc5f6b31f))
53
+ * retain adopter environment throughout crash histories ([f7b8713](https://github.com/gigaverse-app/due/commit/f7b871301d6ca376f39d43ae59449e0da343b9e1))
54
+
55
+
56
+ ### Performance
57
+
58
+ * publish immutable revisions cheaply with application outcome proofs ([f68e3e4](https://github.com/gigaverse-app/due/commit/f68e3e41098134c33fc0aab3fe351885c9157e30))
59
+ * remove per-publication staging directories without weakening recovery ([4ce9e34](https://github.com/gigaverse-app/due/commit/4ce9e3495068a3496e38f57587a23aa251f7f7bc))
60
+
61
+
62
+ ### Documentation
63
+
64
+ * add coming-from guides for Python background-work libraries ([a65ee04](https://github.com/gigaverse-app/due/commit/a65ee0471ab51b28a4cde5897ff928f3fee5e806))
65
+ * add focused coming-from guides for Python work libraries ([054e65c](https://github.com/gigaverse-app/due/commit/054e65c2a86101ca9ba7fa7c440e957788660222))
66
+ * audit backend migration readiness ([#6](https://github.com/gigaverse-app/due/issues/6)) ([07e4b8b](https://github.com/gigaverse-app/due/commit/07e4b8be06563130475679a6c81484aa3632a5c4))
67
+ * compare Python queues and document migration and shim boundaries ([0893cd5](https://github.com/gigaverse-app/due/commit/0893cd5797961c731dc12eeb79737f6756599e4d))
68
+ * establish in-repository example catalog ([599c43f](https://github.com/gigaverse-app/due/commit/599c43f637d6eb97e6513a2ee9c169a2c719c1e9))
69
+ * explain Due strengths, tradeoffs and evidence boundaries ([4e635bc](https://github.com/gigaverse-app/due/commit/4e635bcfd1dde336ff4a5ddd9bd5b5f3f5c8c5ae))
70
+ * explain Due strengths, tradeoffs and evidence boundaries ([2d8e2dd](https://github.com/gigaverse-app/due/commit/2d8e2dd7a7c0aca2eeacc1ee78fd87a3561854a8))
71
+ * explain Temporal parity gaps and scheduled demo tradeoffs ([4998a18](https://github.com/gigaverse-app/due/commit/4998a18de69f6946728796d413a60964a6c70efa))
72
+ * format migration examples and check Markdown before commit ([fc6978d](https://github.com/gigaverse-app/due/commit/fc6978dfd751daf892c0edae6e96ce8573f1d088))
73
+ * guide conformance adoption and separate public authoring APIs ([6e0c061](https://github.com/gigaverse-app/due/commit/6e0c061c3a339e96803ffa3d81fb30817f5a6bcb))
74
+ * introduce Due durable obligations library ([3ac929f](https://github.com/gigaverse-app/due/commit/3ac929f175d25de951125a219d41c20d1b3b00b4))
75
+ * keep concurrent runtime adoption audit separate ([118486f](https://github.com/gigaverse-app/due/commit/118486f7a430bbb56864342870522dffd302efd8))
76
+ * link deadline wakeup evidence and completed recovery checks ([3752750](https://github.com/gigaverse-app/due/commit/37527507b6c4a79a30ad635ae390bfe11a6039dd))
77
+ * pin the companion harness audit reference ([2f48257](https://github.com/gigaverse-app/due/commit/2f48257ee403f91009a29c6df015c9f89d758fd7))
78
+ * plan application outcome and provider replay proofs ([b06ba90](https://github.com/gigaverse-app/due/commit/b06ba90322f9bc2cee3af19c5a1a7f5ebbef6464))
79
+ * plan audit-driven integration and recovery guides ([62f8688](https://github.com/gigaverse-app/due/commit/62f868824649409407963ea4427396d5a9da7087))
80
+ * plan backend replacement contract parity ([086b1be](https://github.com/gigaverse-app/due/commit/086b1bead3aa5c09524f7db732f71cea6b94f77a))
81
+ * plan checked immutable-input parity ([10e9eb0](https://github.com/gigaverse-app/due/commit/10e9eb031645ee38b68dc349a1333ce4bcce852a))
82
+ * plan comparative recovery and richer application demos ([a9cde2a](https://github.com/gigaverse-app/due/commit/a9cde2a9f3263d51ceaf19f82553426438c2afd0))
83
+ * plan current backend parity controls ([f8bb0e7](https://github.com/gigaverse-app/due/commit/f8bb0e762e9f1175ddecb1d925c4d9a5c4baf98f))
84
+ * plan executable books convergence guarantees ([9bc29d7](https://github.com/gigaverse-app/due/commit/9bc29d7e9156747eaf35daafdfe8f2cef1184382))
85
+ * plan real adopter integration and third source audit ([24428dc](https://github.com/gigaverse-app/due/commit/24428dc029b04e15bff70567f8545587afb2a34d))
86
+ * plan runtime and provider binding improvements ([3d79a87](https://github.com/gigaverse-app/due/commit/3d79a8789ba1d0a68bbc853950fe5a0b087aca2a))
87
+ * plan scheduled publication demo and recovery proofs ([8fdd8a6](https://github.com/gigaverse-app/due/commit/8fdd8a64822b70a521b5b83f728daae0039731fe))
88
+ * plan work-table parity and contributor workflow ([3d581ef](https://github.com/gigaverse-app/due/commit/3d581ef78a0886a89e0690c4102ded8739ac2b02))
89
+ * record audit port verification and migration limits ([a6d9d1a](https://github.com/gigaverse-app/due/commit/a6d9d1aeab4646be4d210f5aa333d50c88688d46))
90
+ * record binding integrity and integration evidence ([bf95077](https://github.com/gigaverse-app/due/commit/bf95077a634f70d0e94e000e64930e7537d8f5ed))
91
+ * record comparison and recovery validation evidence ([65f7cdc](https://github.com/gigaverse-app/due/commit/65f7cdcedcb5997f056b586293f9bd98f9c755bb))
92
+ * record complete serial consumer validation ([92433ad](https://github.com/gigaverse-app/due/commit/92433adfb9934f8c6d758434edbc7571cb14960d))
93
+ * record completed package and backend parity checks ([d779b1c](https://github.com/gigaverse-app/due/commit/d779b1cc8d838865883a6915c3713dcf7fbe55e4))
94
+ * record scheduled publication recovery evidence ([ff87b07](https://github.com/gigaverse-app/due/commit/ff87b074a9e44391189a5246c356a9321f2139bb))
95
+ * record standalone verification and supported Django baseline ([22153f1](https://github.com/gigaverse-app/due/commit/22153f1281c7fe87b4a64f688bc246994c2f8c4f))
96
+ * record the publication demo Procrastinate provenance ([a896b12](https://github.com/gigaverse-app/due/commit/a896b128102aaf01dbe0df497259e893f188c9fc))
97
+ * record work-table parity verification ([f5b4464](https://github.com/gigaverse-app/due/commit/f5b446407d3fba8e428725067d722069e89fd2c0))
98
+ * show concrete APIs and code changes in migration guides ([205bde7](https://github.com/gigaverse-app/due/commit/205bde743c989bd1721cbd543cdef4dd9a453f4e))
99
+ * start competitor migration audit ([7d625a8](https://github.com/gigaverse-app/due/commit/7d625a82af8477abf6f0428ae9373dde1afb1e8d))
@@ -0,0 +1,75 @@
1
+ # Contributing to Due
2
+
3
+ Due uses Python 3.14 and uv. Install Docker (or supply dedicated PostgreSQL and
4
+ Redis instances), then:
5
+
6
+ ```bash
7
+ uv sync --locked
8
+ uv run pre-commit install
9
+ docker compose up -d --wait
10
+ uv run pre-commit run --all-files
11
+ uv run pytest --due-work-require-assessed --due-work-profile-report=profiles.json
12
+ uv run python scripts/check_adoption_report.py profiles.json --contract "Due replay-safe work table" --verified A B D I J
13
+ DJANGO_SETTINGS_MODULE=examples.settings uv run python -m django makemigrations --check --dry-run
14
+ uv build
15
+ ```
16
+
17
+ `uv.lock` is committed. Dependency edits need `uv lock`; normal development and
18
+ CI use `--locked`. Pre-commit runs Ruff lint/format on staged Python files and
19
+ Pyrefly on the whole project. Hooks can modify formatting; review and stage those
20
+ changes before committing again. Database and worker tests run separately from
21
+ commit hooks so a commit does not depend on Docker availability.
22
+
23
+ Tests use real PostgreSQL. `pytest-django` creates and drops its test database;
24
+ the configured user must be allowed to create databases. The worker integration
25
+ tests also use Redis and separate Celery prefork processes. The live books
26
+ journeys additionally start a real Django HTTP server and Celery Beat, verifying
27
+ normal form submission and scheduled recovery of either lost notification. Set
28
+ `DUE_DATABASE_URL` and `DUE_BROKER_URL` for dedicated test services, or use the defaults in
29
+ [compose.yaml](compose.yaml). Stop local services with `docker compose down`.
30
+
31
+ ## Changes and proofs
32
+
33
+ Keep the public API focused on work tables. The delivery lease in
34
+ `runtime/_delivery.py` is private machinery for observation workers; it is not a
35
+ public native-table composition API. Use [the capability guide](docs/capabilities.md)
36
+ to find the existing owner of behavior before adding another abstraction.
37
+
38
+ For behavioral fixes, first write a failing history at the boundary that broke:
39
+ commit, publication, provider call, evidence, or local settlement. Prefer real
40
+ transactions and selectors. Fault injection may replace transport or the
41
+ provider; it must not replace the production decision being proved. Include a
42
+ control that demonstrates the fault was reached, and observe the product result.
43
+
44
+ ## Pull requests and CI
45
+
46
+ Use Conventional Commit titles (`feat:`, `fix:`, `docs:`, `test:`, `ci:`,
47
+ `refactor:`, `build:`, `perf:`, `revert:`, `chore:`), enforced by the PR-title
48
+ workflow. Explain the resulting behavior, relevant validation and limitations.
49
+
50
+ CI has independent lint/workflow validation, Pyrefly, distribution, and
51
+ PostgreSQL/Redis test jobs. The test suite runs against locked Django and the
52
+ minimum supported Django version, including the live HTTP/worker/Beat journeys.
53
+ Obligation reports, process logs and distributions are retained as run artifacts.
54
+ The distribution job builds through the sdist, then imports the wheel with
55
+ isolated Python and no development dependencies.
56
+
57
+ `main` requires `lint`, `typecheck`, `tests (locked)`, `tests (minimum)`,
58
+ `build` and `conventional-commit` to pass from GitHub Actions, with the branch
59
+ up to date before merging. These repository protections apply to administrators
60
+ too. Preserve these check names when changing CI, or update branch protection
61
+ together with the workflow.
62
+
63
+ To reproduce the installed-wheel check:
64
+
65
+ ```bash
66
+ uv build
67
+ uv venv /tmp/due-wheel
68
+ uv pip install --python /tmp/due-wheel dist/*.whl
69
+ /tmp/due-wheel/bin/python -I scripts/check_wheel.py
70
+ ```
71
+
72
+ Releases are not automatic yet; the GitHub installation in the README is the
73
+ supported distribution path. Creating a public repository does not reserve its
74
+ PyPI package name. Configure and verify PyPI ownership and Trusted Publishing
75
+ before adding a release workflow that uploads distributions.