consequa-x 1.2.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. consequa_x-2.1.0/CHANGELOG.md +353 -0
  2. {consequa_x-1.2.0 → consequa_x-2.1.0}/MANIFEST.in +2 -0
  3. consequa_x-2.1.0/PKG-INFO +277 -0
  4. consequa_x-2.1.0/README.md +242 -0
  5. consequa_x-2.1.0/docs/application-integration.md +179 -0
  6. consequa_x-2.1.0/docs/design-2.0.md +109 -0
  7. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/design.md +2 -2
  8. consequa_x-2.1.0/docs/framework-integration.md +212 -0
  9. consequa_x-2.1.0/docs/migrating-to-2.0.md +100 -0
  10. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/offline-reports.md +16 -5
  11. consequa_x-2.1.0/docs/opentelemetry.md +119 -0
  12. consequa_x-2.1.0/docs/product-roadmap.md +124 -0
  13. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/quickstart.md +24 -13
  14. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/release-notes.md +58 -0
  15. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/research-roadmap.md +5 -4
  16. consequa_x-2.1.0/docs/stable-api.md +122 -0
  17. {consequa_x-1.2.0 → consequa_x-2.1.0}/examples/agent_loop_sqlite.py +8 -8
  18. {consequa_x-1.2.0 → consequa_x-2.1.0}/examples/artifact_delivery.py +33 -33
  19. {consequa_x-1.2.0 → consequa_x-2.1.0}/pyproject.toml +6 -1
  20. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/analyze_matched_local_study.py +7 -7
  21. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/audit_interaction_sampling.py +10 -10
  22. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/audit_refund_interactions.py +1 -1
  23. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/audit_release_artifacts.py +3 -2
  24. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/build_public_docs.py +6 -6
  25. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/build_site_demo.py +10 -9
  26. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/check_installed_release.py +280 -77
  27. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/export_render_site.py +1 -1
  28. consequa_x-2.1.0/scripts/refresh_sample_report.py +61 -0
  29. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/run_matched_trace_judge.py +1 -1
  30. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/run_tau_benchmark_validation.py +18 -18
  31. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/run_upstream_car_study.py +5 -3
  32. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/summarize_matched_execution.py +2 -2
  33. consequa_x-2.1.0/src/consequa_x/__init__.py +55 -0
  34. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/attribution.py +3 -1
  35. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/decision_replay.py +6 -5
  36. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/evaluation.py +8 -8
  37. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/interaction_sampling.py +1 -1
  38. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/payments.py +5 -4
  39. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/policy_experiment.py +5 -5
  40. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/policy_runner.py +17 -15
  41. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/runner.py +25 -20
  42. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/targets.py +1 -1
  43. consequa_x-2.1.0/src/consequa_x/capture.py +560 -0
  44. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/cli.py +301 -6
  45. consequa_x-2.1.0/src/consequa_x/compare.py +106 -0
  46. consequa_x-2.1.0/src/consequa_x/composite.py +335 -0
  47. consequa_x-2.1.0/src/consequa_x/errors.py +35 -0
  48. consequa_x-2.1.0/src/consequa_x/explanation.py +222 -0
  49. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/graph.py +26 -15
  50. consequa_x-2.1.0/src/consequa_x/guard.py +79 -0
  51. consequa_x-2.1.0/src/consequa_x/integrations/__init__.py +166 -0
  52. consequa_x-2.1.0/src/consequa_x/integrations/claude_agent_sdk.py +93 -0
  53. consequa_x-2.1.0/src/consequa_x/integrations/langchain.py +82 -0
  54. consequa_x-2.1.0/src/consequa_x/integrations/openai_agents.py +101 -0
  55. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/mcp_capture.py +10 -6
  56. consequa_x-2.1.0/src/consequa_x/migrate.py +180 -0
  57. consequa_x-2.1.0/src/consequa_x/models.py +733 -0
  58. consequa_x-2.1.0/src/consequa_x/otel.py +621 -0
  59. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/policies.py +6 -12
  60. consequa_x-2.1.0/src/consequa_x/readback.py +106 -0
  61. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/record_verifier.py +61 -61
  62. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/report.py +166 -52
  63. consequa_x-2.1.0/src/consequa_x/research.py +22 -0
  64. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/schema.py +8 -5
  65. consequa_x-1.2.0/src/consequa_x/schemas/trace-v0.1.json → consequa_x-2.1.0/src/consequa_x/schemas/trace-v1.0.json +617 -543
  66. consequa_x-2.1.0/src/consequa_x/store.py +57 -0
  67. consequa_x-2.1.0/src/consequa_x/summary.py +142 -0
  68. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/verification.py +137 -25
  69. consequa_x-2.1.0/src/consequa_x.egg-info/PKG-INFO +277 -0
  70. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x.egg-info/SOURCES.txt +37 -2
  71. consequa_x-2.1.0/src/consequa_x.egg-info/requires.txt +18 -0
  72. consequa_x-2.1.0/tests/fixtures/v0.1/README.md +13 -0
  73. consequa_x-2.1.0/tests/fixtures/v0.1/record-timeout-after-commit.json +234 -0
  74. consequa_x-2.1.0/tests/fixtures/v0.1/refund-another-actor.json +267 -0
  75. consequa_x-2.1.0/tests/fixtures/v0.1/refund-stale-readback.json +273 -0
  76. consequa_x-2.1.0/tests/fixtures/v0.1/refund-timeout-after-commit.explanation.json +455 -0
  77. consequa_x-2.1.0/tests/fixtures/v0.1/refund-timeout-after-commit.json +273 -0
  78. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_agent_loop_example.py +1 -1
  79. consequa_x-2.1.0/tests/test_async_capture.py +98 -0
  80. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_calibration.py +1 -1
  81. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_calibration_mechanisms.py +1 -1
  82. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_capture.py +49 -35
  83. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_cli.py +1 -1
  84. consequa_x-2.1.0/tests/test_compare_verify_redact.py +95 -0
  85. consequa_x-2.1.0/tests/test_composite.py +331 -0
  86. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_coalition.py +6 -3
  87. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_contrastive.py +3 -2
  88. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_replay.py +7 -5
  89. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_shapley.py +2 -1
  90. consequa_x-2.1.0/tests/test_docs_examples.py +20 -0
  91. consequa_x-2.1.0/tests/test_errors.py +87 -0
  92. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_graph.py +13 -9
  93. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_graph_identity.py +6 -6
  94. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_installed_release_check.py +14 -0
  95. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_integration.py +28 -28
  96. consequa_x-2.1.0/tests/test_integrations.py +339 -0
  97. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_interval_replay.py +3 -3
  98. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_baseline_audit.py +4 -4
  99. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_local_study.py +6 -6
  100. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_trace_judge.py +8 -7
  101. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_mcp_capture.py +1 -1
  102. consequa_x-2.1.0/tests/test_migrate.py +118 -0
  103. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_model_eval_integration.py +4 -4
  104. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_models.py +90 -50
  105. consequa_x-2.1.0/tests/test_multi_action.py +165 -0
  106. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_ollama.py +2 -2
  107. consequa_x-2.1.0/tests/test_otel.py +235 -0
  108. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_payments.py +5 -4
  109. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_policies.py +4 -4
  110. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_policy_experiment.py +3 -3
  111. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_policy_experiment_integration.py +5 -5
  112. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_policy_runner.py +11 -10
  113. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_public_integration.py +76 -88
  114. consequa_x-2.1.0/tests/test_readback_guard.py +96 -0
  115. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_record_verifier.py +46 -29
  116. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_refund_interactions.py +1 -1
  117. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_release_inventory.py +1 -1
  118. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_replay_targets.py +4 -3
  119. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_report.py +45 -41
  120. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_report_cli.py +3 -3
  121. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_research_integration.py +1 -1
  122. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_schema.py +14 -13
  123. consequa_x-2.1.0/tests/test_summary_store.py +105 -0
  124. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_task_templates.py +1 -1
  125. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_tau_benchmark_validation.py +5 -5
  126. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_verification.py +7 -4
  127. consequa_x-1.2.0/CHANGELOG.md +0 -180
  128. consequa_x-1.2.0/PKG-INFO +0 -225
  129. consequa_x-1.2.0/README.md +0 -198
  130. consequa_x-1.2.0/docs/application-integration.md +0 -145
  131. consequa_x-1.2.0/docs/framework-integration.md +0 -110
  132. consequa_x-1.2.0/docs/product-roadmap.md +0 -106
  133. consequa_x-1.2.0/docs/stable-api.md +0 -100
  134. consequa_x-1.2.0/src/consequa_x/__init__.py +0 -28
  135. consequa_x-1.2.0/src/consequa_x/capture.py +0 -376
  136. consequa_x-1.2.0/src/consequa_x/explanation.py +0 -216
  137. consequa_x-1.2.0/src/consequa_x/models.py +0 -532
  138. consequa_x-1.2.0/src/consequa_x.egg-info/PKG-INFO +0 -225
  139. consequa_x-1.2.0/src/consequa_x.egg-info/requires.txt +0 -6
  140. {consequa_x-1.2.0 → consequa_x-2.1.0}/CONTRIBUTING.md +0 -0
  141. {consequa_x-1.2.0 → consequa_x-2.1.0}/LICENSE +0 -0
  142. {consequa_x-1.2.0 → consequa_x-2.1.0}/SECURITY.md +0 -0
  143. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/attribution-calibration.md +0 -0
  144. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/build-contract.md +0 -0
  145. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/car-reproduction-plan.md +0 -0
  146. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/completion-plan.md +0 -0
  147. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/decision-contrastive.md +0 -0
  148. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/decision-replay.md +0 -0
  149. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/decision-shapley.md +0 -0
  150. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/graph-witnesses.md +0 -0
  151. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/interaction-sampling.md +0 -0
  152. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/interval-followup-plan.md +0 -0
  153. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/launch-readiness.md +0 -0
  154. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/local-pypi-setup.md +0 -0
  155. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/matched-trace-judge.md +0 -0
  156. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/policy-evaluation.md +0 -0
  157. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/policy-replay.md +0 -0
  158. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/refund-interactions.md +0 -0
  159. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/release-readiness.md +0 -0
  160. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/studies/matched-local-2026-10-18.json +0 -0
  161. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/studies/refund-family-candidates-v1.json +0 -0
  162. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/study-manifests.md +0 -0
  163. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/study-plan.md +0 -0
  164. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/tau-benchmark-validation.md +0 -0
  165. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/upstream-car-comparison.md +0 -0
  166. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/v1.1-release.md +0 -0
  167. {consequa_x-1.2.0 → consequa_x-2.1.0}/docs/variable-length-game-plan.md +0 -0
  168. {consequa_x-1.2.0 → consequa_x-2.1.0}/examples/decision_shapley_fixture.py +0 -0
  169. {consequa_x-1.2.0 → consequa_x-2.1.0}/examples/report_quickstart.py +0 -0
  170. {consequa_x-1.2.0 → consequa_x-2.1.0}/requirements-dev.lock +0 -0
  171. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/audit_interval_comparison.py +0 -0
  172. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/audit_review_revision.py +0 -0
  173. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/build_matched_study_figures.py +0 -0
  174. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/configure_pypi_auth.py +0 -0
  175. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/draw_paper_diagrams.py +0 -0
  176. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/finalize_interval_artifacts.py +0 -0
  177. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/finalize_matched_local_study.py +0 -0
  178. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/finalize_refund_artifacts.py +0 -0
  179. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/plot_interval_comparison.py +0 -0
  180. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/plot_paper_results.py +0 -0
  181. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/publish_alpha.py +0 -0
  182. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/publish_release.py +0 -0
  183. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/run_interaction_sampling.py +0 -0
  184. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/run_matched_local_study.py +0 -0
  185. {consequa_x-1.2.0 → consequa_x-2.1.0}/scripts/summarize_interaction_sampling.py +0 -0
  186. {consequa_x-1.2.0 → consequa_x-2.1.0}/setup.cfg +0 -0
  187. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/__main__.py +0 -0
  188. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/adapters/__init__.py +0 -0
  189. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/adapters/ollama.py +0 -0
  190. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/__init__.py +0 -0
  191. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/assessment_metrics.py +0 -0
  192. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/calibration.py +0 -0
  193. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/calibration_export.py +0 -0
  194. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/calibration_mechanisms.py +0 -0
  195. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/decision_coalition.py +0 -0
  196. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/decision_contrastive.py +0 -0
  197. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/decision_shapley.py +0 -0
  198. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/interaction_export.py +0 -0
  199. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/interaction_mechanisms.py +0 -0
  200. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/interval_comparison.py +0 -0
  201. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/intervals.py +0 -0
  202. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/study.py +0 -0
  203. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/benchmark/templates.py +0 -0
  204. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x/py.typed +0 -0
  205. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x.egg-info/dependency_links.txt +0 -0
  206. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x.egg-info/entry_points.txt +0 -0
  207. {consequa_x-1.2.0 → consequa_x-2.1.0}/src/consequa_x.egg-info/top_level.txt +0 -0
  208. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_assessment_metrics.py +0 -0
  209. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_attribution.py +0 -0
  210. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_calibration_cli.py +0 -0
  211. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_contrastive_cli.py +0 -0
  212. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_decision_shapley_cli.py +0 -0
  213. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_interaction_sampling.py +0 -0
  214. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_interaction_sampling_cli.py +0 -0
  215. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_interaction_workers.py +0 -0
  216. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_interval_comparison.py +0 -0
  217. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_intervals.py +0 -0
  218. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_execution_summary.py +0 -0
  219. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_figure_builder.py +0 -0
  220. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_matched_study_finalizer.py +0 -0
  221. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_policy_evaluation.py +0 -0
  222. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_prompt_profile_cli.py +0 -0
  223. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_refund_interactions_cli.py +0 -0
  224. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_release_helpers.py +0 -0
  225. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_render_site_export.py +0 -0
  226. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_site_demo.py +0 -0
  227. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_snapshot_integrity.py +0 -0
  228. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_stable_release.py +0 -0
  229. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_study.py +0 -0
  230. {consequa_x-1.2.0 → consequa_x-2.1.0}/tests/test_upstream_car_study.py +0 -0
@@ -0,0 +1,353 @@
1
+ # Changes
2
+
3
+ ## 2.1.0 - 19 October 2026
4
+
5
+ Additive: the roadmap features left out of 2.0.0 (verifier composition,
6
+ framework integrations and OpenTelemetry). Schema `1.0` and the 2.0 API are
7
+ unchanged, and the core still has no required runtime dependency. Checked
8
+ before publication; see the
9
+ [release record](output/release-2.1.0-2026-10-19/README.md).
10
+
11
+ - Verifier composition. `all_of(contract_id, *parts)` and `any_of(...)` build
12
+ one outcome contract from part contracts, each with its own predicate,
13
+ expected values and timing; `contract_parts` decodes and checks them.
14
+ `CompositeVerifier({part_id: verifier}, sources={part_id: source})` checks
15
+ each part against the readback from its source and combines the receipts
16
+ with three-valued logic: `all_of` is violated when any part is violated and
17
+ satisfied when all are; `any_of` is satisfied when any part is and violated
18
+ when all are; otherwise the outcome stays `unknown`. A part without readback
19
+ is `unknown`. The receipt keeps each part's evidence (tagged with its part
20
+ ID, status, origin and reason), the union of the parts' effects and
21
+ findings, and adds `PART_VIOLATED`, `PART_UNKNOWN` and `PART_OTHER_ACTOR`.
22
+ Target matching is conservative, so an agent's report is judged only when
23
+ the deciding parts did target matching. Parts can nest.
24
+ - Several readbacks per verification: `verify`, `averify`,
25
+ `ActionCapture.verify`/`averify` and `poll_readback` (whose `read` may return
26
+ one observation per source) accept a sequence of observations for a verifier
27
+ that provides `verify_readbacks`. Receipts are still checked against every
28
+ supplied observation.
29
+ - Reports describe an `all_of`/`any_of` contract's structure (part count,
30
+ each part's deadline and horizon) and list each recorded part result, without
31
+ showing part payloads.
32
+ - `consequa-x verify` takes `--readback` once per source, plus
33
+ `--part-source PART=SOURCE` and `--scope-field PART=FIELD` for composite
34
+ contracts.
35
+ - OpenTelemetry (`consequa_x.otel`): `to_otlp` writes an OTLP/JSON document
36
+ with a span per action, an `execute_tool` span per attempt named as the GenAI
37
+ semantic conventions describe, and a span per verification, with
38
+ `consequa_x.*` attributes for state, origin, alignment and diagnosis codes.
39
+ Payloads are opt-in (`include_payloads=True`, which also embeds the complete
40
+ trace for `from_otlp`). `emit` creates the spans through `opentelemetry-api`
41
+ (extra `otel`). `record_tool_spans` turns `execute_tool` spans from any
42
+ GenAI instrumentation into recorded actions for the contracts the
43
+ application supplies. New commands: `otel-export` and `otel-import`.
44
+ - Framework integrations (`consequa_x.integrations`): `ToolCallCapture` and
45
+ `ToolCall` record framework tool calls for the calls `contract_for` makes
46
+ consequential, grouping retries through `action_id_for`. Optional extras:
47
+ `openai-agents` (`consequential_tool`, in place of `function_tool`),
48
+ `langchain` (`ConsequaCallbackHandler`) and `claude-agent-sdk`
49
+ (`consequa_hooks` for `PreToolUse`, `PostToolUse` and
50
+ `PostToolUseFailure`). Tested offline with openai-agents 0.24.0,
51
+ langchain-core 1.6.12, claude-agent-sdk 0.2.168 and opentelemetry 1.45.1; no
52
+ live model was called.
53
+
54
+ ## 2.0.0 - 19 October 2026 (breaking)
55
+
56
+ See [the 2.0 design](docs/design-2.0.md) and the
57
+ [migration guide](docs/migrating-to-2.0.md). Deferred to 2.1: verifier
58
+ composition, optional framework integrations and OpenTelemetry export.
59
+ Published to PyPI with registry hashes verified; see the
60
+ [release record](output/release-2.0.0-2026-10-19/README.md). Installed checks
61
+ passed on Windows Python 3.11.9 and 3.12.10, on one Alpine Linux 3.24.2 QEMU guest
62
+ with Python 3.14.8 and from a fresh PyPI install. macOS has never been tested.
63
+
64
+ - Typed exceptions: every intentional error derives from `ConsequaError` and
65
+ still from `ValueError` or `TypeError`. `ValidationError` (invalid records,
66
+ traces and settings; malformed JSON is now one too), `SchemaVersionError`,
67
+ `ConsequaTypeError`, `ContractError` (a verifier cannot evaluate the
68
+ contract), `ReceiptError` (a verifier or matcher result crosses its identity
69
+ boundary, or recorded evidence cannot support the interpretation) and
70
+ `RecorderError`. `InsufficientEvidenceError` and `PolicyError` join the
71
+ hierarchy.
72
+ - Captured payloads are deeply read-only. Event data, arguments, contract
73
+ expectations, results, readback records, scopes and evidence details are
74
+ `FrozenDict` and `FrozenList` values: they compare equal to and serialize
75
+ like ordinary dicts and lists, but any change raises `ConsequaTypeError`.
76
+ `copy.deepcopy` returns the same read-only value; `thaw()` returns an
77
+ editable copy, and `to_dict()` still exports ordinary dicts and lists.
78
+ - Trace schema `1.0`. A trace holds one or more `actions`, each with its own
79
+ contract; `responses`, `assessments` (zero or more per action) and
80
+ `verifications` each name their `action_id`. A required `time_base`
81
+ (`unix_ms` or `relative_ms`) says what the integer millisecond times count
82
+ from. `trace_id` is no longer repeated on actions and events. All records
83
+ are keyword-only. Schema `0.1` input is refused with a `SchemaVersionError`
84
+ that names the migration route; the packaged schema is `trace-v1.0.json`.
85
+ New helpers: `Trace.get_action`, `single_action`, `responses_for`,
86
+ `assessments_for`, `verifications_for`, `latest_assessment`,
87
+ `latest_verification`.
88
+ - `TraceRecorder.register` can be called for several actions and returns an
89
+ `ActionCapture` whose `attempt`, `call`, `dispatch`, `response`,
90
+ `assessment` and `verify` record for that action. The recorder-level methods
91
+ still work while exactly one action is registered. Assessments are optional
92
+ and may be repeated. The default clock is wall-clock `unix_ms`; a custom
93
+ clock records `relative_ms` unless told otherwise. `capture_tool` and
94
+ `call_mcp_tool` accept an `ActionCapture`.
95
+ - `explain()` returns a `TraceExplanation` with one `ActionExplanation` per
96
+ action (`for_action`, `single_action`). An action without verification is
97
+ reported as `NO_VERIFICATION` instead of raising. The evidence graph has a
98
+ contract node per action, and offline reports show every action, with an
99
+ Action column for responses and verifications and the time base in the
100
+ footer.
101
+ - Verifiers own domain interpretation. `VerificationResult` gains
102
+ `target_effect_ids` (`None` when the verifier did no target matching,
103
+ otherwise this action's effects that match the full target) and `findings`
104
+ (`Finding(code, effect_ids, detail)`). `RefundVerifier` records refund
105
+ matches and the `EXCESS_EFFECTS`, `DUPLICATE_EFFECT`, `PARAMETER_MISMATCH`,
106
+ `PARTIAL_EFFECT` and `REVERSED_EFFECT` findings; `RecordVerifier` records
107
+ record matches and `EXCESS_EFFECTS`, `DUPLICATE_EFFECT`,
108
+ `PARAMETER_MISMATCH` and `REMOVED_EFFECT`. `TargetMatcher`,
109
+ `RecordTargetMatcher`, `RecordVerifier.target_matcher()` and
110
+ `explain(..., target_matcher=...)` are removed; a custom verifier sets
111
+ `target_effect_ids` instead.
112
+ - `explain()` is domain-independent: it reads receipts, responses and
113
+ assessments and never reinterprets evidence details. Diagnoses are
114
+ structured `Diagnosis(code, evidence, message)` records; `codes` gives the
115
+ codes and `diagnosis` a display label. `UNASSESSABLE_ASSESSMENT` now applies
116
+ to every predicate whenever the outcome is known but alignment cannot be
117
+ judged (1.x omitted it for refunds). `CORE_DIAGNOSES` lists the codes
118
+ `explain()` produces.
119
+ - Offline reports show each action's assessment alignment and diagnosis
120
+ codes, computed from the recorded receipts. Codes from custom verifiers are
121
+ counted rather than printed.
122
+ - Migration: `migrate_trace()` and `consequa-x migrate OLD --output NEW`
123
+ convert schema `0.1` traces. Target matches and findings are added only when
124
+ the 2.0 verifier (the refund verifier by default; pass others with
125
+ `verifiers=`) reproduces the recorded receipt exactly; no recorded conclusion
126
+ is changed. `consequa-x validate` checks trace files. Migrated traces of the
127
+ 1.x demo reproduce their 1.x explanations; fixtures written by the released
128
+ 1.2.0 package are in `tests/fixtures/v0.1`.
129
+ - `summarize(traces)` and `consequa-x summarize PATH... [--format text|markdown|json]`
130
+ count verified state, origin, alignment, tool responses and diagnoses over
131
+ every action, with stated denominators; `unknown` and `unverified` stay
132
+ separate from failures, and actions with divergences or violations are
133
+ listed. Folders (non-trace JSON is skipped and counted) and `.jsonl` stores
134
+ are accepted; invalid inputs are listed by path and error type only and make
135
+ the command exit 2.
136
+ - `poll_readback(capture, read, until_ms=, interval_ms=)` waits until the
137
+ contract horizon, then reads back and verifies repeatedly (every observation
138
+ and receipt is recorded) until the outcome is `satisfied` or `violated` or the
139
+ time limit passes; an unresolved `unknown` is returned as is.
140
+ - Async agents: `capture_tool` wraps `async def` tools, `ActionCapture.acall`
141
+ (and `TraceRecorder.acall`) awaits a tool as one recorded attempt,
142
+ `averify`/`ActionCapture.averify` accept verifiers whose `verify` is a
143
+ coroutine (receipts are checked exactly as `verify` checks them), and
144
+ `apoll_readback` polls with awaited reads and `asyncio.sleep`.
145
+ - `retry_advice(receipt or trace)` turns verified evidence into
146
+ `DO_NOT_RETRY` (the outcome already holds, whoever produced it), `WAIT`
147
+ (missing or unknown readback), `ESCALATE` (relevant effects that do not
148
+ satisfy the contract) or `RETRY_PERMITTED` (a complete readback shows no
149
+ relevant effect; retry with an idempotency key, since an in-flight attempt can
150
+ still commit), each with a reason.
151
+ - `compare(left, right)` and `consequa-x compare A B [--fail-on-difference]`
152
+ compare two traces action by action: contract, tool responses, latest
153
+ assessment, verified state and origin, alignment and diagnosis codes, plus
154
+ actions present in only one trace.
155
+ - `consequa-x verify TRACE --readback OBS.json [--scope-field F] --output NEW`
156
+ verifies a captured readback file with the built-in refund or record
157
+ verifier and saves the trace with the new receipt, without Python code.
158
+ - `render_report(..., include_details=True, redact=("card_number", ...))` and
159
+ `consequa-x report --include-details --redact KEY` replace the values of the
160
+ named JSON keys everywhere in the included trace. Values under other keys are
161
+ kept; this is omission by name, not anonymization.
162
+ - `TraceStore(path)`: an append-only JSON Lines file of validated traces with
163
+ unique trace IDs; reading reports the line number of an invalid entry.
164
+ - Research interfaces (`EffectEstimate`, `Intervention`, `leave_one_out`,
165
+ `recency_attribution`, the policy types) are imported from
166
+ `consequa_x.research` instead of the top-level namespace.
167
+ - Research code (benchmark, replay, policies, studies and their audit
168
+ scripts) produces and reads schema `1.0` traces. Retained 1.x study outputs
169
+ under `output/` are unchanged.
170
+
171
+ ## 1.2.0 - 19 October 2026
172
+
173
+ Additive only: the 1.x API and trace schema `0.1` are unchanged.
174
+
175
+ - Added `TraceRecorder` (`consequa_x.capture`), which records one action as it
176
+ happens (context, decision, registration with its outcome contract,
177
+ dispatches, tool responses, the agent's assessment, readbacks and
178
+ verification) and returns an ordinary validated `Trace`. Events are linked
179
+ as in the package fixtures, so graphs, reports and `explain()` work unchanged.
180
+ - Added tool-call capture: `TraceRecorder.attempt()` (context manager),
181
+ `TraceRecorder.call()` and the `capture_tool` decorator record the dispatch
182
+ and the response (success, `timeout` for `TimeoutError`, or `error`) around
183
+ a synchronous tool, keep JSON results, keep only exception type names, and
184
+ re-raise. A recorded timeout says nothing about whether the effect happened.
185
+ - Added `RecordVerifier` and `RecordTargetMatcher` for a generic `record_present`
186
+ predicate: records with given field values, an exact or minimum count,
187
+ a commit deadline and a persistence window, with configurable field names.
188
+ Unavailable, out-of-scope, incomplete, stale or malformed readback stays
189
+ `unknown`, and origin stays a separate conclusion, as for refunds.
190
+ - Added `examples/agent_loop_sqlite.py`: a stdlib-only, offline tool-calling
191
+ loop that writes to a real SQLite database, is captured with `TraceRecorder`,
192
+ and is verified through a separate read-only connection with `RecordVerifier`.
193
+ Modes: `timeout_after_commit`, `other_actor` and `stale_readback`.
194
+ It is also in the website's quickstart download.
195
+ - README section on capturing a real agent's tool call.
196
+ - Added `TraceRecorder.now()`, the recorder clock for readback times.
197
+ - Added `consequa_x.mcp_capture.call_mcp_tool`, which records an awaited MCP
198
+ tool call from any session exposing `call_tool(name, arguments)` without an
199
+ MCP dependency. Tool content is not copied into the trace.
200
+ - Added a framework integration guide (`docs/framework-integration.md`).
201
+ - The website's workflow cards, documentation and quickstart show the capture
202
+ API. `scripts/check_installed_release.py` now also exercises the recorder,
203
+ tool capture and record verifier from the installed wheel.
204
+ - Published to PyPI with registry hashes verified; see the
205
+ [release record](output/release-1.2.0-2026-10-19/README.md). Installed checks
206
+ passed on Windows Python 3.11.9 and 3.12.10, on one Alpine Linux 3.24.2 QEMU
207
+ guest with Python 3.14.8 and from a fresh PyPI install. macOS has never been
208
+ tested.
209
+
210
+ ## 1.1.1 - 18 October 2026
211
+
212
+ - Documentation and metadata release. Runtime code and schema `0.1` are
213
+ identical to 1.1.0 apart from the version number.
214
+ - Rewrote the package description for PyPI with absolute links that work outside
215
+ the repository. Project URLs now point to the public source repository and to
216
+ <https://consequa-x.onrender.com>.
217
+ - The source repository is public. Its issue forms and security policy replace
218
+ the separate community repository, whose quickstart and release notes moved to
219
+ `docs/quickstart.md` and `docs/release-notes.md`.
220
+ - The website inspector and live demo replay recorded output from real package
221
+ runs, generated by `scripts/build_site_demo.py` and pinned by
222
+ `tests/test_site_demo.py`. The site deploys from this repository.
223
+ - The snapshot-integrity test now verifies every committed manifest format and
224
+ ignores uncommitted study outputs.
225
+ - Published to PyPI with registry hashes verified; see the
226
+ [release record](output/release-1.1.1-2026-10-18/README.md). Installed checks
227
+ passed on Windows Python 3.11.9 and 3.12.10 and from a fresh PyPI install.
228
+ Linux and macOS were not rerun for 1.1.1; macOS has never been tested.
229
+
230
+ ## 1.1.0 - 17 October 2026
231
+
232
+ - Added `render_report(trace, include_details=False)` and
233
+ `consequa-x report trace.json --output report.html`, with a self-contained
234
+ chronology, contract, responses, assessment, readback, verification/origin and
235
+ SVG evidence graph plus complete accessible graph tables.
236
+ - Default reports omit arbitrary captured values throughout the file. Explicit
237
+ details mode includes the full trace as escaped inert JSON. No report executes
238
+ actions, verifiers, target matchers or replay; alignment remains unassessable
239
+ in the report. The original trace remains separate evidence.
240
+ - Preserved source and existing output files with exclusive creation. Invalid
241
+ schema data is refused before an output directory is created, with captured
242
+ values omitted from report-command decoding errors.
243
+ - Added a synthetic artifact-delivery visual quickstart and public documentation,
244
+ support and security routes, while retaining the private research repository.
245
+ - Added installed-package release checks and browser/report security gates.
246
+ Release receipts bind the final artifact, actual platform checks and
247
+ publication state; public release notes report the tested environments.
248
+ - Preserved the dependency-free version-1 core and portable wire schema `0.1`.
249
+ GitHub Actions stays disabled.
250
+
251
+ ## Post-release research update - 16 October 2026
252
+
253
+ The predeclared physical-interaction study finished collection on 15 October
254
+ 2026 at frozen runtime source `0bd744df4fc8784e4cf1a1e2eb62f892c6f3c8c9`.
255
+ It retained all 2,048 trials and 655,360 planned branch slots, with 628,535 actual
256
+ scripted policy calls, no model calls and no additional comparison calls.
257
+ The [protocol](output/interaction-sampling-2026-10-15/protocol.json),
258
+ [complete summary](output/interaction-sampling-2026-10-15/summary.json) and
259
+ [execution receipt](output/interaction-sampling-2026-10-15-execution.json) retain
260
+ the collection identity separately from the public stable release. The
261
+ [independent audit](output/interaction-sampling-audits-2026-10-15/independent.json)
262
+ passed 44,698,925 assertions, covering every planned trial/branch and 4,210
263
+ preselected complete traces. The
264
+ [derived findings](output/interaction-sampling-findings-2026-10-15/FINDINGS.md)
265
+ retain coverage, width, detection and refusal denominators. The defined
266
+ framework and protocol/software paper scope is complete on 16 October 2026:
267
+ the [illustrated eight-page IEEE PDF](output/pdf/Consequa-X_IEEE_Paper.pdf) compiled and all
268
+ rendered pages passed visual review. The [QA receipt](output/pdf/qa.json) binds
269
+ it to the frozen [editable source](paper/consequa-x-ieee.tex) and four vector
270
+ figures. Actual venue selection, final human
271
+ review, reviewer access and submission remain maintainer steps. These results
272
+ do not establish held-out model performance, a new estimator or baseline
273
+ superiority.
274
+
275
+ ## 1.0.0 - 15 October 2026
276
+
277
+ Runtime source is frozen at `0bd744df4fc8784e4cf1a1e2eb62f892c6f3c8c9`.
278
+ The [stable release is public on PyPI](https://pypi.org/project/consequa-x/1.0.0/),
279
+ built from `85ce6c316838c995782aadc8c10770acc708339b` with all 36 runtime files
280
+ matching that freeze. Both downloads were independently hash/size checked;
281
+ [publication](output/release-1.0.0-2026-10-15/publication.json) and
282
+ [fresh registry-install](output/release-1.0.0-2026-10-15/registry-install.json)
283
+ receipts record the achieved release. PR #8 merged as `708d064`; GitHub remains
284
+ private. Published artifacts retain their original reviewed bytes and dated
285
+ build-time documentation.
286
+
287
+ - Defined the version 1 stable evidence-core API while retaining wire schema
288
+ `0.1`. Benchmark procedures, exact policy prompts and study commands remain
289
+ explicitly scoped research interfaces.
290
+ - Added explicit application verifiers to `verify(..., verifier=...)`, with
291
+ receipt checks for contract, observation identity, source, watermark and
292
+ capture time. Adapter semantics and source authentication remain application
293
+ responsibilities.
294
+ - Added `TargetMatcher` and `explain(..., target_matcher=...)`. Non-refund
295
+ predicates remain domain-neutral and unassessable without declared target
296
+ semantics; unknown receipts never execute the matcher. Invalid adapter methods
297
+ and inputs have controlled type errors, and invalid target returns or known
298
+ refund details have controlled value errors.
299
+ - Exported `Evidence`, `ToolResponse`, `ResponseStatus` and `TargetMatcher` from
300
+ the package root. Added the standalone artifact-delivery application example
301
+ and source-archive integration documentation.
302
+ - Preserved successive and duplicate effect records as separate graph witnesses,
303
+ with identity edges and observation-specific verification/origin links.
304
+ Conflicting later payloads or provenance cannot overwrite an earlier witness.
305
+ Source-owned reserved fields remain available verbatim; attribution candidates
306
+ must identify captured events.
307
+ - Made demonstration, fixture-experiment and explanation output paths preserve
308
+ existing evidence. Run directories must be new or empty; explanation output
309
+ must be a new file distinct from the input trace.
310
+ - Added `calibrate-interactions`, reproducible repeated physical refund sampling,
311
+ same-draw uncertainty comparisons, bounded parallel execution, complete
312
+ refusal/cost records and an independently implemented audit. The retained
313
+ 2,048-trial collection completed after the distribution-build checkpoint;
314
+ its later research status is recorded above without changing released bytes.
315
+
316
+ The full frozen-source suite passed 1,480 tests and 240 subtests. Twenty
317
+ additional stable-publisher tests passed; final installed-wheel Windows Python
318
+ 3.11.9 conformance passed 200 tests and 165 subtests. Independent Windows Python
319
+ 3.12.14 wheel, source-archive and registry installations each passed 12 trace
320
+ round-trips and four artifact-adapter checks. All eight local release gates,
321
+ public artifact hash/size verification and the fresh registry installation are
322
+ complete. No GitHub Actions were used. These software checks do not establish
323
+ held-out model performance or attribution superiority.
324
+
325
+ ## 0.1.0a2 — 14 October 2026
326
+
327
+ - Default decision-contrastive uncertainty now uses exact binomial intervals.
328
+ Signed Shapley pair means use Hoeffding bounds; independent endpoint
329
+ differences use two exact binomial marginals with a split failure allowance.
330
+ Original bootstrap/normal modes remain explicit comparators.
331
+ - Added `compare-intervals`, with a pre-call protocol, complete same-draw
332
+ retention, exact finite distribution calculations, width/power metrics and
333
+ independent numerical/artifact audits. Original calibration data is preserved.
334
+ - Added an explicit on-reach positional game for normally terminated later
335
+ decisions. The strict game remains the default, and incompatible operations,
336
+ unknown evidence, provider failures and budget refusals remain explicit.
337
+ - Added `refund-interactions` to enumerate physical selection/retry interactions,
338
+ idempotency and evidence/budget controls through actual payment readback.
339
+ - Interval rescoring now reconstructs Shapley pair vectors from replay evidence
340
+ and validates stored coverage, points and endpoint diagnostics.
341
+ - Cached static record annotations while retaining validation of every value;
342
+ added a working paper, reproducible evidence links and release preparation.
343
+
344
+ This is an engineering alpha. Sampling assumptions, individual-interval scope
345
+ and intervention games remain explicit. Synthetic validation does not establish
346
+ live-model calibration, cross-task generalization or attribution superiority.
347
+ GitHub Actions remains disabled; checks and builds run locally.
348
+
349
+ ## 0.1.0a1
350
+
351
+ Initial Python alpha with portable evidence records, independent refund
352
+ verification, evidence graphs, local policy adapters and bounded replay
353
+ experiments. No registry publication is implied by the source version.
@@ -5,3 +5,5 @@ recursive-include docs/studies *.json
5
5
  recursive-include tests *.py
6
6
  recursive-include examples *.py
7
7
  recursive-include scripts *.py
8
+ recursive-include tests/fixtures *.json
9
+ recursive-include tests/fixtures *.md
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.4
2
+ Name: consequa-x
3
+ Version: 2.1.0
4
+ Summary: Evidence-aware explanation of consequential agent actions
5
+ Author: Devrajsinh Jhala
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://consequa-x.onrender.com
8
+ Project-URL: Documentation, https://consequa-x.onrender.com/docs.html
9
+ Project-URL: Changelog, https://consequa-x.onrender.com/changelog.html
10
+ Project-URL: Repository, https://github.com/Devrajsinh-Jhala/consequa-x
11
+ Project-URL: Issues, https://github.com/Devrajsinh-Jhala/consequa-x/issues
12
+ Project-URL: Security, https://github.com/Devrajsinh-Jhala/consequa-x/security/policy
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Provides-Extra: claude-agent-sdk
22
+ Requires-Dist: claude-agent-sdk>=0.2.168; extra == "claude-agent-sdk"
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8; extra == "dev"
25
+ Requires-Dist: build>=1.2; extra == "dev"
26
+ Requires-Dist: ruff>=0.8; extra == "dev"
27
+ Requires-Dist: jsonschema>=4.23; extra == "dev"
28
+ Provides-Extra: langchain
29
+ Requires-Dist: langchain-core>=1.6; extra == "langchain"
30
+ Provides-Extra: openai-agents
31
+ Requires-Dist: openai-agents>=0.24; extra == "openai-agents"
32
+ Provides-Extra: otel
33
+ Requires-Dist: opentelemetry-api>=1.45; extra == "otel"
34
+ Dynamic: license-file
35
+
36
+ # Consequa-X
37
+
38
+ **Evidence-aware explanation of consequential agent actions.**
39
+
40
+ When an agent calls a tool that changes something (a refund, a delivery, a
41
+ database write), the tool's response is only part of the story. A timeout can
42
+ hide a refund that went through. A "success" can hide one that never landed.
43
+ Another actor can produce the very outcome the agent was asked for.
44
+
45
+ Consequa-X keeps four things apart: the **tool response**, what the **agent
46
+ reported**, the outcome established by an **independent read-only readback**, and
47
+ **who produced the effect**. Missing, stale or incomplete evidence stays
48
+ `unknown` instead of being guessed.
49
+
50
+ - Website, live inspector and docs: <https://consequa-x.onrender.com>
51
+ - Package: <https://pypi.org/project/consequa-x/>
52
+ - Source and issues: <https://github.com/Devrajsinh-Jhala/consequa-x>
53
+
54
+ Python 3.11+ · MIT licensed · no required runtime dependencies · no model, API
55
+ key or network access needed for the core or the offline examples.
56
+
57
+ ## Install
58
+
59
+ ```sh
60
+ python -m pip install consequa-x
61
+ consequa-x --version
62
+ ```
63
+
64
+ Use `python -m consequa_x` wherever a command below uses `consequa-x`. Optional
65
+ extras add framework integrations and OpenTelemetry: `consequa-x[openai-agents]`,
66
+ `consequa-x[langchain]`, `consequa-x[claude-agent-sdk]` and `consequa-x[otel]`.
67
+
68
+ ## See it in a minute
69
+
70
+ ```sh
71
+ consequa-x demo --output my-demo
72
+ consequa-x report my-demo/traces/episode_01.json --output my-report.html
73
+ ```
74
+
75
+ `demo` writes twelve synthetic refund scenarios with simulated money: timeouts
76
+ before and after commit, false success, partial and duplicate effects, delayed
77
+ readback, retries, another actor and missing provenance. Episode 1 is a timeout
78
+ after commit: the tool timed out and the agent reported failure, but readback
79
+ shows the refund committed and linked to the agent's action. Open
80
+ `my-report.html` in any browser. It is one self-contained file with no scripts
81
+ or network requests.
82
+
83
+ Each run needs a new output directory, and a report never overwrites an existing
84
+ file. The demo's `evaluator_truth/` folder is simulator ground truth for
85
+ evaluation only; never pass it to an explainer.
86
+
87
+ ## Use it in Python
88
+
89
+ Register each consequential action with its intended outcome before running it,
90
+ let the recorder capture what happens, read the outcome back from a trusted
91
+ read-only source, then verify and explain:
92
+
93
+ ```python
94
+ from consequa_x import (
95
+ Observation, OutcomeContract, RecordVerifier, TraceRecorder, explain, render_report,
96
+ )
97
+
98
+ verifier = RecordVerifier(scope_fields=("order_id",))
99
+ rec = TraceRecorder("run-17", actor="support-agent", time_base="relative_ms")
100
+ refund = rec.register(
101
+ "refund-o-17", "issue_refund", {"order_id": "o-17"}, at_ms=0,
102
+ contract=OutcomeContract(contract_id="refund-o-17", predicate="record_present",
103
+ expected={"order_id": "o-17", "amount_minor": 5000},
104
+ deadline_ms=200, stability_ms=50))
105
+
106
+ try:
107
+ with refund.attempt(at_ms=5) as attempt: # your tool call goes here
108
+ attempt.at_ms = 30
109
+ raise TimeoutError # ...and it timed out
110
+ except TimeoutError:
111
+ refund.assessment("failure", at_ms=31) # what the agent reported
112
+
113
+ # Captured independently, after the horizon, from a read-only replica of the orders table.
114
+ readback = Observation(
115
+ observation_id="read-1", source="orders-replica", observed_at_ms=300, as_of_ms=300,
116
+ scope={"order_id": "o-17"},
117
+ records=({"effect_id": "rf-1", "order_id": "o-17", "amount_minor": 5000,
118
+ "committed_at_ms": 20, "action_id": "refund-o-17",
119
+ "attempt_id": "refund-o-17:attempt-1", "actor": "support-agent"},))
120
+ receipt = refund.verify(readback, verifier=verifier)
121
+
122
+ result = explain(rec.trace()).for_action("refund-o-17")
123
+ assert receipt.status.value == "satisfied" # the refund really happened
124
+ assert receipt.origin.value == "confirmed" # and this action produced it
125
+ assert result.assessment_alignment == "contradicted" # the agent said failure
126
+ print(result.codes) # ('ASSESSMENT_DIVERGENCE', 'ACKNOWLEDGEMENT_EFFECT_DIVERGENCE')
127
+ html = render_report(rec.trace()) # offline, minimal disclosure
128
+ ```
129
+
130
+ A run can register several actions; each `register` returns that action's
131
+ `ActionCapture`, and its attempts, assessments and verifications stay separate.
132
+ `capture_tool` decorates a tool (synchronous or `async def`) so every call is
133
+ recorded. `poll_readback` re-reads a lagging source until the outcome is known,
134
+ and `retry_advice` turns the receipt into a retry decision.
135
+
136
+ The built-in verifiers are `RecordVerifier` (rows, orders, tickets, files:
137
+ `record_present`) and `RefundVerifier` (`refund_processed`). Both check values,
138
+ count, commit deadline and persistence; unavailable, incomplete, wrongly scoped or
139
+ stale readback produces `unknown`. Effect origin is a separate conclusion:
140
+ `confirmed`, `other_actor` or `unknown`. Verifiers also record which effects match
141
+ the target and domain findings (excess, duplicate, mismatched, reversed or
142
+ removed effects); `explain` reads those receipts without any domain logic of its
143
+ own.
144
+
145
+ The [agent-loop example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/agent_loop_sqlite.py)
146
+ runs this end to end against a real SQLite database, offline, in three modes: a
147
+ timeout after the refund committed, a refund made by someone else, and a readback
148
+ too stale to decide. The
149
+ [framework guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/framework-integration.md)
150
+ shows where the calls go in OpenAI Agents SDK, LangChain, Claude Agent SDK and MCP
151
+ tool loops.
152
+
153
+ Traces round-trip through a portable, versioned JSON schema (`1.0`):
154
+ `Trace.from_json(trace.to_json())` rejects unknown fields, broken identity links
155
+ and dependency cycles, and every captured payload is read-only.
156
+
157
+ ## Bring your own domain
158
+
159
+ Write a read-only `Verifier` for your predicate. It returns a
160
+ `VerificationResult` with the state, origin and the effects it saw; to let the
161
+ agent's report be judged, it also records `target_effect_ids` (this action's
162
+ effects that match the full target):
163
+
164
+ ```python
165
+ receipt = verify(action, observation, verifier=MyVerifier())
166
+ ```
167
+
168
+ Your application owns source trust, scope, completeness, timing and provenance;
169
+ Consequa-X checks that receipts bind to the supplied action, contract and
170
+ observation, and keeps the evidence structured. The
171
+ [artifact-delivery example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/artifact_delivery.py)
172
+ implements a verifier with public APIs only, and the
173
+ [integration guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/application-integration.md)
174
+ describes the boundary in detail. The
175
+ [stable API](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/stable-api.md)
176
+ page lists what version 2 guarantees.
177
+
178
+ An outcome with several required effects (a refund *and* a closed ticket, or a
179
+ refund *or* store credit) is one contract: `all_of(...)` or `any_of(...)` over
180
+ part contracts, checked by `CompositeVerifier` with one readback per source.
181
+ Unknown parts keep the whole outcome unknown unless another part already
182
+ settles it.
183
+
184
+ ## Agent frameworks and OpenTelemetry
185
+
186
+ Optional integrations record an agent framework's tool calls through the same
187
+ recorder. Your `contract_for(call)` decides which calls are consequential:
188
+
189
+ ```python
190
+ from consequa_x.integrations import ToolCallCapture
191
+ calls = ToolCallCapture(rec, contract_for=contract_for)
192
+
193
+ # OpenAI Agents SDK: use in place of @function_tool
194
+ from consequa_x.integrations.openai_agents import consequential_tool
195
+ # LangChain: config={"callbacks": [ConsequaCallbackHandler(calls)]}
196
+ from consequa_x.integrations.langchain import ConsequaCallbackHandler
197
+ # Claude Agent SDK: ClaudeAgentOptions(hooks=consequa_hooks(calls))
198
+ from consequa_x.integrations.claude_agent_sdk import consequa_hooks
199
+ ```
200
+
201
+ `consequa_x.otel` writes traces as OTLP/JSON with `execute_tool` spans named as
202
+ the OpenTelemetry GenAI conventions describe, emits them through
203
+ `opentelemetry-api`, and turns tool spans from other instrumentation into
204
+ recorded actions. See the
205
+ [framework guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/framework-integration.md)
206
+ and the
207
+ [OpenTelemetry guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/opentelemetry.md).
208
+
209
+ ## Upgrading from 1.x
210
+
211
+ Version 2.0 changes the trace schema to `1.0` (several actions per trace, a
212
+ declared time base, keyword-only and read-only records) and moves domain
213
+ interpretation into verifiers. Convert saved 1.x traces with
214
+ `consequa-x migrate OLD.json --output NEW.json` or `migrate_trace()`. The
215
+ [migration guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/migrating-to-2.0.md)
216
+ lists every change and its replacement.
217
+
218
+ ## Command line
219
+
220
+ | Command | What it does |
221
+ | --- | --- |
222
+ | `consequa-x demo --output DIR` | Write the twelve synthetic refund scenarios: traces, explanations, schema and manifest |
223
+ | `consequa-x explain TRACE [--output FILE]` | Explain an existing trace without replay; prints JSON or writes a new file |
224
+ | `consequa-x report TRACE --output FILE` | Render a self-contained HTML report; `--include-details` embeds the full capture, `--redact KEY` blanks named keys in it |
225
+ | `consequa-x summarize PATH... [--format markdown]` | Count outcomes, alignment and divergences across trace files, folders and `.jsonl` stores |
226
+ | `consequa-x compare A B` | Compare two traces action by action |
227
+ | `consequa-x verify TRACE --readback OBS --output NEW` | Verify captured readback with built-in verifiers; repeat `--readback` for an `all_of`/`any_of` contract |
228
+ | `consequa-x otel-export TRACE --output FILE` / `consequa-x otel-import FILE --output-dir DIR` | Write a trace as OpenTelemetry OTLP/JSON spans; restore traces exported with `--include-payloads` |
229
+ | `consequa-x validate TRACE...` / `consequa-x migrate OLD --output NEW` | Check traces; convert schema `0.1` traces |
230
+ | `consequa-x experiment …` and research commands | Paired replay, decision attribution and calibration studies (see Research) |
231
+
232
+ ## What it does not do
233
+
234
+ - It does not watch or control a live agent; your application captures the records.
235
+ `retry_advice` is advice derived from captured evidence, not a guarantee.
236
+ - It does not authenticate a readback source or prove that provider metadata is true.
237
+ - An evidence-graph link records provenance, not causal necessity.
238
+ - Default reports omit captured strings and identifiers, but keep times, counts
239
+ and relationships. That is field omission, not anonymization.
240
+ - No accuracy advantage over other methods is claimed.
241
+
242
+ ## Research
243
+
244
+ The repository also contains declared research interfaces, imported from
245
+ `consequa_x.research`: isolated replay, contrastive and Shapley-style decision attribution,
246
+ calibration studies, an optional local Ollama adapter, and the retained evidence
247
+ for each study. Results so far are synthetic or exploratory local-model studies
248
+ and are reported with their denominators and limits. Start with the
249
+ [research roadmap](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/research-roadmap.md)
250
+ and the [paper notes](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/paper/README.md).
251
+
252
+ ## Platforms
253
+
254
+ The package is pure Python. Released wheels have been install-tested on Windows
255
+ with Python 3.11 and 3.12 and on one Alpine Linux virtual machine with Python
256
+ 3.14. macOS has not been tested yet. See the
257
+ [release notes](https://consequa-x.onrender.com/changelog.html) for exact
258
+ environments.
259
+
260
+ ## Contributing and support
261
+
262
+ - Questions and bugs: [GitHub issues](https://github.com/Devrajsinh-Jhala/consequa-x/issues/new/choose).
263
+ Use synthetic data only; never post real traces, customer data or credentials.
264
+ - Security: report vulnerabilities privately as described in
265
+ [SECURITY.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/SECURITY.md).
266
+ - Development: see [CONTRIBUTING.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/CONTRIBUTING.md).
267
+
268
+ ```sh
269
+ python -m pip install -e ".[dev]"
270
+ python -m pytest
271
+ python -m ruff check src tests scripts
272
+ ```
273
+
274
+ ## License
275
+
276
+ MIT, copyright Devrajsinh Jhala. The website's self-hosted fonts keep their SIL
277
+ Open Font License.