consequa-x 1.1.0__tar.gz → 1.2.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.
- {consequa_x-1.1.0 → consequa_x-1.2.0}/CHANGELOG.md +54 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/CONTRIBUTING.md +23 -11
- consequa_x-1.2.0/PKG-INFO +225 -0
- consequa_x-1.2.0/README.md +198 -0
- consequa_x-1.2.0/SECURITY.md +24 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/application-integration.md +21 -1
- consequa_x-1.2.0/docs/framework-integration.md +110 -0
- consequa_x-1.2.0/docs/matched-trace-judge.md +119 -0
- consequa_x-1.2.0/docs/product-roadmap.md +106 -0
- consequa_x-1.2.0/docs/quickstart.md +85 -0
- consequa_x-1.2.0/docs/release-notes.md +62 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/release-readiness.md +9 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/research-roadmap.md +20 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/stable-api.md +8 -0
- consequa_x-1.2.0/docs/studies/matched-local-2026-10-18.json +376 -0
- consequa_x-1.2.0/docs/tau-benchmark-validation.md +154 -0
- consequa_x-1.2.0/docs/upstream-car-comparison.md +178 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/v1.1-release.md +5 -0
- consequa_x-1.2.0/examples/agent_loop_sqlite.py +204 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/pyproject.toml +6 -6
- consequa_x-1.2.0/scripts/analyze_matched_local_study.py +474 -0
- consequa_x-1.2.0/scripts/audit_review_revision.py +213 -0
- consequa_x-1.2.0/scripts/build_matched_study_figures.py +482 -0
- consequa_x-1.2.0/scripts/build_public_docs.py +471 -0
- consequa_x-1.2.0/scripts/build_site_demo.py +270 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/check_installed_release.py +117 -1
- consequa_x-1.2.0/scripts/export_render_site.py +385 -0
- consequa_x-1.2.0/scripts/finalize_matched_local_study.py +204 -0
- consequa_x-1.2.0/scripts/run_matched_local_study.py +529 -0
- consequa_x-1.2.0/scripts/run_matched_trace_judge.py +664 -0
- consequa_x-1.2.0/scripts/run_tau_benchmark_validation.py +650 -0
- consequa_x-1.2.0/scripts/run_upstream_car_study.py +907 -0
- consequa_x-1.2.0/scripts/summarize_matched_execution.py +407 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/__init__.py +7 -4
- consequa_x-1.2.0/src/consequa_x/capture.py +376 -0
- consequa_x-1.2.0/src/consequa_x/mcp_capture.py +49 -0
- consequa_x-1.2.0/src/consequa_x/record_verifier.py +260 -0
- consequa_x-1.2.0/src/consequa_x.egg-info/PKG-INFO +225 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x.egg-info/SOURCES.txt +37 -0
- consequa_x-1.2.0/tests/test_agent_loop_example.py +61 -0
- consequa_x-1.2.0/tests/test_capture.py +249 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_installed_release_check.py +21 -0
- consequa_x-1.2.0/tests/test_matched_baseline_audit.py +153 -0
- consequa_x-1.2.0/tests/test_matched_execution_summary.py +215 -0
- consequa_x-1.2.0/tests/test_matched_figure_builder.py +199 -0
- consequa_x-1.2.0/tests/test_matched_local_study.py +415 -0
- consequa_x-1.2.0/tests/test_matched_study_finalizer.py +152 -0
- consequa_x-1.2.0/tests/test_matched_trace_judge.py +304 -0
- consequa_x-1.2.0/tests/test_mcp_capture.py +73 -0
- consequa_x-1.2.0/tests/test_record_verifier.py +169 -0
- consequa_x-1.2.0/tests/test_render_site_export.py +125 -0
- consequa_x-1.2.0/tests/test_site_demo.py +85 -0
- consequa_x-1.2.0/tests/test_snapshot_integrity.py +60 -0
- consequa_x-1.2.0/tests/test_tau_benchmark_validation.py +164 -0
- consequa_x-1.2.0/tests/test_upstream_car_study.py +301 -0
- consequa_x-1.1.0/PKG-INFO +0 -308
- consequa_x-1.1.0/README.md +0 -281
- consequa_x-1.1.0/SECURITY.md +0 -12
- consequa_x-1.1.0/scripts/build_public_docs.py +0 -273
- consequa_x-1.1.0/src/consequa_x.egg-info/PKG-INFO +0 -308
- consequa_x-1.1.0/tests/test_snapshot_integrity.py +0 -20
- {consequa_x-1.1.0 → consequa_x-1.2.0}/LICENSE +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/MANIFEST.in +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/attribution-calibration.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/build-contract.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/car-reproduction-plan.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/completion-plan.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/decision-contrastive.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/decision-replay.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/decision-shapley.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/design.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/graph-witnesses.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/interaction-sampling.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/interval-followup-plan.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/launch-readiness.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/local-pypi-setup.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/offline-reports.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/policy-evaluation.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/policy-replay.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/refund-interactions.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/studies/refund-family-candidates-v1.json +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/study-manifests.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/study-plan.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/docs/variable-length-game-plan.md +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/examples/artifact_delivery.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/examples/decision_shapley_fixture.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/examples/report_quickstart.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/requirements-dev.lock +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/audit_interaction_sampling.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/audit_interval_comparison.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/audit_refund_interactions.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/audit_release_artifacts.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/configure_pypi_auth.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/draw_paper_diagrams.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/finalize_interval_artifacts.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/finalize_refund_artifacts.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/plot_interval_comparison.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/plot_paper_results.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/publish_alpha.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/publish_release.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/run_interaction_sampling.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/scripts/summarize_interaction_sampling.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/setup.cfg +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/__main__.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/adapters/__init__.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/adapters/ollama.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/attribution.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/__init__.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/assessment_metrics.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/calibration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/calibration_export.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/calibration_mechanisms.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/decision_coalition.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/decision_contrastive.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/decision_replay.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/decision_shapley.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/evaluation.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/interaction_export.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/interaction_mechanisms.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/interaction_sampling.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/interval_comparison.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/intervals.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/payments.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/policy_experiment.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/policy_runner.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/runner.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/study.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/targets.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/benchmark/templates.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/explanation.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/graph.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/models.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/policies.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/py.typed +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/report.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/schema.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/schemas/trace-v0.1.json +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x/verification.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x.egg-info/dependency_links.txt +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x.egg-info/entry_points.txt +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x.egg-info/requires.txt +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/src/consequa_x.egg-info/top_level.txt +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_assessment_metrics.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_attribution.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_calibration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_calibration_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_calibration_mechanisms.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_coalition.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_contrastive.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_contrastive_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_replay.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_shapley.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_decision_shapley_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_graph.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_graph_identity.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_integration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_interaction_sampling.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_interaction_sampling_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_interaction_workers.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_interval_comparison.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_interval_replay.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_intervals.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_model_eval_integration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_models.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_ollama.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_payments.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_policies.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_policy_evaluation.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_policy_experiment.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_policy_experiment_integration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_policy_runner.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_prompt_profile_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_public_integration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_refund_interactions.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_refund_interactions_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_release_helpers.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_release_inventory.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_replay_targets.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_report.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_report_cli.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_research_integration.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_schema.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_stable_release.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_study.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_task_templates.py +0 -0
- {consequa_x-1.1.0 → consequa_x-1.2.0}/tests/test_verification.py +0 -0
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 1.2.0 - 19 October 2026
|
|
4
|
+
|
|
5
|
+
Additive only: the 1.x API and trace schema `0.1` are unchanged.
|
|
6
|
+
|
|
7
|
+
- Added `TraceRecorder` (`consequa_x.capture`), which records one action as it
|
|
8
|
+
happens (context, decision, registration with its outcome contract,
|
|
9
|
+
dispatches, tool responses, the agent's assessment, readbacks and
|
|
10
|
+
verification) and returns an ordinary validated `Trace`. Events are linked
|
|
11
|
+
as in the package fixtures, so graphs, reports and `explain()` work unchanged.
|
|
12
|
+
- Added tool-call capture: `TraceRecorder.attempt()` (context manager),
|
|
13
|
+
`TraceRecorder.call()` and the `capture_tool` decorator record the dispatch
|
|
14
|
+
and the response (success, `timeout` for `TimeoutError`, or `error`) around
|
|
15
|
+
a synchronous tool, keep JSON results, keep only exception type names, and
|
|
16
|
+
re-raise. A recorded timeout says nothing about whether the effect happened.
|
|
17
|
+
- Added `RecordVerifier` and `RecordTargetMatcher` for a generic `record_present`
|
|
18
|
+
predicate: records with given field values, an exact or minimum count,
|
|
19
|
+
a commit deadline and a persistence window, with configurable field names.
|
|
20
|
+
Unavailable, out-of-scope, incomplete, stale or malformed readback stays
|
|
21
|
+
`unknown`, and origin stays a separate conclusion, as for refunds.
|
|
22
|
+
- Added `examples/agent_loop_sqlite.py`: a stdlib-only, offline tool-calling
|
|
23
|
+
loop that writes to a real SQLite database, is captured with `TraceRecorder`,
|
|
24
|
+
and is verified through a separate read-only connection with `RecordVerifier`.
|
|
25
|
+
Modes: `timeout_after_commit`, `other_actor` and `stale_readback`.
|
|
26
|
+
It is also in the website's quickstart download.
|
|
27
|
+
- README section on capturing a real agent's tool call.
|
|
28
|
+
- Added `TraceRecorder.now()`, the recorder clock for readback times.
|
|
29
|
+
- Added `consequa_x.mcp_capture.call_mcp_tool`, which records an awaited MCP
|
|
30
|
+
tool call from any session exposing `call_tool(name, arguments)` without an
|
|
31
|
+
MCP dependency. Tool content is not copied into the trace.
|
|
32
|
+
- Added a framework integration guide (`docs/framework-integration.md`).
|
|
33
|
+
- The website's workflow cards, documentation and quickstart show the capture
|
|
34
|
+
API. `scripts/check_installed_release.py` now also exercises the recorder,
|
|
35
|
+
tool capture and record verifier from the installed wheel.
|
|
36
|
+
|
|
37
|
+
## 1.1.1 - 18 October 2026
|
|
38
|
+
|
|
39
|
+
- Documentation and metadata release. Runtime code and schema `0.1` are
|
|
40
|
+
identical to 1.1.0 apart from the version number.
|
|
41
|
+
- Rewrote the package description for PyPI with absolute links that work outside
|
|
42
|
+
the repository. Project URLs now point to the public source repository and to
|
|
43
|
+
<https://consequa-x.onrender.com>.
|
|
44
|
+
- The source repository is public. Its issue forms and security policy replace
|
|
45
|
+
the separate community repository, whose quickstart and release notes moved to
|
|
46
|
+
`docs/quickstart.md` and `docs/release-notes.md`.
|
|
47
|
+
- The website inspector and live demo replay recorded output from real package
|
|
48
|
+
runs, generated by `scripts/build_site_demo.py` and pinned by
|
|
49
|
+
`tests/test_site_demo.py`. The site deploys from this repository.
|
|
50
|
+
- The snapshot-integrity test now verifies every committed manifest format and
|
|
51
|
+
ignores uncommitted study outputs.
|
|
52
|
+
- Published to PyPI with registry hashes verified; see the
|
|
53
|
+
[release record](output/release-1.1.1-2026-10-18/README.md). Installed checks
|
|
54
|
+
passed on Windows Python 3.11.9 and 3.12.10 and from a fresh PyPI install.
|
|
55
|
+
Linux and macOS were not rerun for 1.1.1; macOS has never been tested.
|
|
56
|
+
|
|
3
57
|
## 1.1.0 - 17 October 2026
|
|
4
58
|
|
|
5
59
|
- Added `render_report(trace, include_details=False)` and
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
# Contributing to Consequa-X
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Thanks for helping. This public repository holds the Python package, its tests
|
|
4
|
+
and documentation, the website, and the research records behind the paper. The
|
|
5
|
+
current release is on [PyPI](https://pypi.org/project/consequa-x/). It separates
|
|
6
|
+
a stable application evidence core from declared research interfaces (refund
|
|
7
|
+
simulation, programmatic policies, replay attribution and an optional local
|
|
8
|
+
Ollama adapter). Recorded studies establish declared implementation behavior,
|
|
9
|
+
not empirical superiority or a new causal estimator. Preserve original samples
|
|
10
|
+
when adding prompt profiles or evaluations.
|
|
11
|
+
|
|
12
|
+
Start with the [README](README.md), [design](docs/design.md), and
|
|
13
|
+
[research roadmap](docs/research-roadmap.md). The
|
|
14
|
+
[policy replay guide](docs/policy-replay.md) covers bounded context comparisons
|
|
15
|
+
and evidence exports. Release receipts under `output/release-*` record the exact
|
|
16
|
+
artifacts and installation checks for each published version.
|
|
17
|
+
|
|
18
|
+
Use a [GitHub issue](https://github.com/Devrajsinh-Jhala/consequa-x/issues/new/choose)
|
|
19
|
+
to discuss a larger adapter, schema change, new domain, or study before investing
|
|
20
|
+
in the implementation. Small fixes and reproducible bug reports can go straight
|
|
21
|
+
to a pull request. Report vulnerabilities privately as described in
|
|
22
|
+
[SECURITY.md](SECURITY.md), never in a public issue.
|
|
10
23
|
|
|
11
24
|
## Set up a development environment
|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
Fork and clone the repository, then create a branch for your change. Use Python 3.11 or 3.12:
|
|
14
27
|
|
|
15
28
|
```sh
|
|
16
29
|
python -m venv .venv
|
|
@@ -32,9 +45,8 @@ python -m ruff check src tests
|
|
|
32
45
|
python -m build
|
|
33
46
|
```
|
|
34
47
|
|
|
35
|
-
GitHub Actions is currently disabled
|
|
36
|
-
|
|
37
|
-
checks above. The retained workflow is manual only and must not be re-enabled
|
|
48
|
+
GitHub Actions is currently disabled for this repository. Automatic push and
|
|
49
|
+
pull-request triggers have been removed; use the local checks above. The retained workflow is manual only and must not be re-enabled
|
|
38
50
|
or dispatched without the maintainer's authorization. Its configured test matrix
|
|
39
51
|
does not establish a current test result. Local release checks include fresh
|
|
40
52
|
package installations and access to the bundled trace schema.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: consequa-x
|
|
3
|
+
Version: 1.2.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: dev
|
|
22
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
25
|
+
Requires-Dist: jsonschema>=4.23; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Consequa-X
|
|
29
|
+
|
|
30
|
+
**Evidence-aware explanation of consequential agent actions.**
|
|
31
|
+
|
|
32
|
+
When an agent calls a tool that changes something (a refund, a delivery, a
|
|
33
|
+
database write), the tool's response is only part of the story. A timeout can
|
|
34
|
+
hide a refund that went through. A "success" can hide one that never landed.
|
|
35
|
+
Another actor can produce the very outcome the agent was asked for.
|
|
36
|
+
|
|
37
|
+
Consequa-X keeps four things apart: the **tool response**, what the **agent
|
|
38
|
+
reported**, the outcome established by an **independent read-only readback**, and
|
|
39
|
+
**who produced the effect**. Missing, stale or incomplete evidence stays
|
|
40
|
+
`unknown` instead of being guessed.
|
|
41
|
+
|
|
42
|
+
- Website, live inspector and docs: <https://consequa-x.onrender.com>
|
|
43
|
+
- Package: <https://pypi.org/project/consequa-x/>
|
|
44
|
+
- Source and issues: <https://github.com/Devrajsinh-Jhala/consequa-x>
|
|
45
|
+
|
|
46
|
+
Python 3.11+ · MIT licensed · no required runtime dependencies · no model, API
|
|
47
|
+
key or network access needed for the core or the offline examples.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
python -m pip install consequa-x
|
|
53
|
+
consequa-x --version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use `python -m consequa_x` wherever a command below uses `consequa-x`.
|
|
57
|
+
|
|
58
|
+
## See it in a minute
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
consequa-x demo --output my-demo
|
|
62
|
+
consequa-x report my-demo/traces/episode_01.json --output my-report.html
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`demo` writes twelve synthetic refund scenarios with simulated money: timeouts
|
|
66
|
+
before and after commit, false success, partial and duplicate effects, delayed
|
|
67
|
+
readback, retries, another actor and missing provenance. Episode 1 is a timeout
|
|
68
|
+
after commit: the tool timed out and the agent reported failure, but readback
|
|
69
|
+
shows the refund committed and linked to the agent's action. Open
|
|
70
|
+
`my-report.html` in any browser. It is one self-contained file with no scripts
|
|
71
|
+
or network requests.
|
|
72
|
+
|
|
73
|
+
Each run needs a new output directory, and a report never overwrites an existing
|
|
74
|
+
file. The demo's `evaluator_truth/` folder is simulator ground truth for
|
|
75
|
+
evaluation only; never pass it to an explainer.
|
|
76
|
+
|
|
77
|
+
## Use it in Python
|
|
78
|
+
|
|
79
|
+
Register the intended outcome before the action, capture what happened, read the
|
|
80
|
+
outcome back from a trusted read-only source, then verify and explain:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from consequa_x import (
|
|
84
|
+
Action, AgentAssessment, AssessmentStatus, Observation, OutcomeContract,
|
|
85
|
+
Trace, explain, render_report, verify,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
expected = {"payment_id": "p1", "amount_minor": 1000, "currency": "INR"}
|
|
89
|
+
contract = OutcomeContract("contract-1", "refund_processed", expected,
|
|
90
|
+
deadline_ms=50, stability_ms=20)
|
|
91
|
+
action = Action("refund-1", "trace-1", "agent", "refund", expected, 0, contract)
|
|
92
|
+
|
|
93
|
+
# In an application, capture this independently from a trusted read-only source.
|
|
94
|
+
observation = Observation(
|
|
95
|
+
"readback-1", "independent-ledger", 100, 100, {"payment_id": "p1"},
|
|
96
|
+
({**expected, "effect_id": "effect-1", "committed_at_ms": 25,
|
|
97
|
+
"status": "processed", "action_id": "refund-1", "actor": "agent"},),
|
|
98
|
+
)
|
|
99
|
+
receipt = verify(action, observation)
|
|
100
|
+
trace = Trace("trace-1", action, (), (),
|
|
101
|
+
AgentAssessment(AssessmentStatus.FAILURE, 10),
|
|
102
|
+
(observation,), (receipt,))
|
|
103
|
+
|
|
104
|
+
assert receipt.status.value == "satisfied" # the refund really happened
|
|
105
|
+
assert receipt.origin.value == "confirmed" # and this action produced it
|
|
106
|
+
assert explain(trace).assessment_alignment == "contradicted" # the agent said failure
|
|
107
|
+
html = render_report(trace) # offline, minimal disclosure
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The built-in `refund_processed` verifier checks payment, integer amount,
|
|
111
|
+
currency, exact count, commit deadline and a persistence window. Unavailable,
|
|
112
|
+
incomplete, wrongly scoped or stale readback produces `unknown`. Effect origin is
|
|
113
|
+
a separate conclusion: `confirmed`, `other_actor` or `unknown`.
|
|
114
|
+
|
|
115
|
+
Traces round-trip through a portable, versioned JSON schema (`0.1`):
|
|
116
|
+
`Trace.from_json(trace.to_json())` rejects unknown fields, broken identity links
|
|
117
|
+
and dependency cycles. `consequa_x.schema.get_trace_schema()` returns the bundled
|
|
118
|
+
JSON Schema.
|
|
119
|
+
|
|
120
|
+
## Capture a real agent's tool call
|
|
121
|
+
|
|
122
|
+
`TraceRecorder` records an action while your agent runs, and `RecordVerifier`
|
|
123
|
+
checks any outcome that leaves records behind (rows, orders, tickets, files):
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from consequa_x import OutcomeContract, RecordVerifier, TraceRecorder, explain
|
|
127
|
+
|
|
128
|
+
contract = OutcomeContract("refund-o-17", "record_present",
|
|
129
|
+
{"order_id": "o-17", "amount_minor": 5000, "currency": "INR"},
|
|
130
|
+
deadline_ms=200, stability_ms=50)
|
|
131
|
+
verifier = RecordVerifier(scope_fields=("order_id",))
|
|
132
|
+
|
|
133
|
+
rec = TraceRecorder("run-17", actor="support-agent")
|
|
134
|
+
rec.register("refund-o-17", "issue_refund", {"order_id": "o-17"}, contract=contract)
|
|
135
|
+
try:
|
|
136
|
+
with rec.attempt(data={"tool": "issue_refund"}) as attempt:
|
|
137
|
+
issue_refund("o-17", attempt_id=attempt.attempt_id) # your tool
|
|
138
|
+
rec.assessment("success") # what the agent reported
|
|
139
|
+
except TimeoutError:
|
|
140
|
+
rec.assessment("failure")
|
|
141
|
+
rec.verify(read_refunds_for("o-17"), verifier=verifier) # your read-only readback
|
|
142
|
+
print(explain(rec.trace(), target_matcher=verifier.target_matcher()).diagnoses)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`capture_tool` decorates a synchronous tool so every call is recorded the same
|
|
146
|
+
way. The
|
|
147
|
+
[agent-loop example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/agent_loop_sqlite.py)
|
|
148
|
+
runs this end to end against a real SQLite database, offline, in three modes:
|
|
149
|
+
a timeout after the refund committed, a refund made by someone else, and a
|
|
150
|
+
readback too stale to decide.
|
|
151
|
+
|
|
152
|
+
## Bring your own domain
|
|
153
|
+
|
|
154
|
+
Supply a read-only `Verifier` for your predicate, and a `TargetMatcher` when the
|
|
155
|
+
agent's reported success or failure should be judged against that contract:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
receipt = verify(action, observation, verifier=MyVerifier())
|
|
159
|
+
explanation = explain(trace, target_matcher=MyTargetMatcher())
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Your application owns source trust, scope, completeness, timing and provenance;
|
|
163
|
+
Consequa-X checks that receipts bind to the supplied contract and observation,
|
|
164
|
+
and keeps the evidence structured. The
|
|
165
|
+
[artifact-delivery example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/artifact_delivery.py)
|
|
166
|
+
implements both adapters with public APIs only, and the
|
|
167
|
+
[integration guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/application-integration.md)
|
|
168
|
+
describes the boundary in detail. The
|
|
169
|
+
[stable API](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/stable-api.md)
|
|
170
|
+
page lists what version 1 guarantees.
|
|
171
|
+
|
|
172
|
+
## Command line
|
|
173
|
+
|
|
174
|
+
| Command | What it does |
|
|
175
|
+
| --- | --- |
|
|
176
|
+
| `consequa-x demo --output DIR` | Write the twelve synthetic refund scenarios: traces, explanations, schema and manifest |
|
|
177
|
+
| `consequa-x explain TRACE [--output FILE]` | Explain an existing trace without replay; prints JSON or writes a new file |
|
|
178
|
+
| `consequa-x report TRACE --output FILE` | Render a self-contained HTML report; add `--include-details` to embed the full capture |
|
|
179
|
+
| `consequa-x experiment …` and research commands | Paired replay, decision attribution and calibration studies (see Research) |
|
|
180
|
+
|
|
181
|
+
## What it does not do
|
|
182
|
+
|
|
183
|
+
- It does not watch or control a live agent; your application captures the records.
|
|
184
|
+
- It does not authenticate a readback source or prove that provider metadata is true.
|
|
185
|
+
- An evidence-graph link records provenance, not causal necessity.
|
|
186
|
+
- Default reports omit captured strings and identifiers, but keep times, counts
|
|
187
|
+
and relationships. That is field omission, not anonymization.
|
|
188
|
+
- No accuracy advantage over other methods is claimed.
|
|
189
|
+
|
|
190
|
+
## Research
|
|
191
|
+
|
|
192
|
+
The repository also contains declared research interfaces, separate from the
|
|
193
|
+
stable core: isolated replay, contrastive and Shapley-style decision attribution,
|
|
194
|
+
calibration studies, an optional local Ollama adapter, and the retained evidence
|
|
195
|
+
for each study. Results so far are synthetic or exploratory local-model studies
|
|
196
|
+
and are reported with their denominators and limits. Start with the
|
|
197
|
+
[research roadmap](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/research-roadmap.md)
|
|
198
|
+
and the [paper notes](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/paper/README.md).
|
|
199
|
+
|
|
200
|
+
## Platforms
|
|
201
|
+
|
|
202
|
+
The package is pure Python. Released wheels have been install-tested on Windows
|
|
203
|
+
with Python 3.11 and 3.12 and on one Alpine Linux virtual machine with Python
|
|
204
|
+
3.14. macOS has not been tested yet. See the
|
|
205
|
+
[release notes](https://consequa-x.onrender.com/changelog.html) for exact
|
|
206
|
+
environments.
|
|
207
|
+
|
|
208
|
+
## Contributing and support
|
|
209
|
+
|
|
210
|
+
- Questions and bugs: [GitHub issues](https://github.com/Devrajsinh-Jhala/consequa-x/issues/new/choose).
|
|
211
|
+
Use synthetic data only; never post real traces, customer data or credentials.
|
|
212
|
+
- Security: report vulnerabilities privately as described in
|
|
213
|
+
[SECURITY.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/SECURITY.md).
|
|
214
|
+
- Development: see [CONTRIBUTING.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/CONTRIBUTING.md).
|
|
215
|
+
|
|
216
|
+
```sh
|
|
217
|
+
python -m pip install -e ".[dev]"
|
|
218
|
+
python -m pytest
|
|
219
|
+
python -m ruff check src tests scripts
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT, copyright Devrajsinh Jhala. The website's self-hosted fonts keep their SIL
|
|
225
|
+
Open Font License.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Consequa-X
|
|
2
|
+
|
|
3
|
+
**Evidence-aware explanation of consequential agent actions.**
|
|
4
|
+
|
|
5
|
+
When an agent calls a tool that changes something (a refund, a delivery, a
|
|
6
|
+
database write), the tool's response is only part of the story. A timeout can
|
|
7
|
+
hide a refund that went through. A "success" can hide one that never landed.
|
|
8
|
+
Another actor can produce the very outcome the agent was asked for.
|
|
9
|
+
|
|
10
|
+
Consequa-X keeps four things apart: the **tool response**, what the **agent
|
|
11
|
+
reported**, the outcome established by an **independent read-only readback**, and
|
|
12
|
+
**who produced the effect**. Missing, stale or incomplete evidence stays
|
|
13
|
+
`unknown` instead of being guessed.
|
|
14
|
+
|
|
15
|
+
- Website, live inspector and docs: <https://consequa-x.onrender.com>
|
|
16
|
+
- Package: <https://pypi.org/project/consequa-x/>
|
|
17
|
+
- Source and issues: <https://github.com/Devrajsinh-Jhala/consequa-x>
|
|
18
|
+
|
|
19
|
+
Python 3.11+ · MIT licensed · no required runtime dependencies · no model, API
|
|
20
|
+
key or network access needed for the core or the offline examples.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
python -m pip install consequa-x
|
|
26
|
+
consequa-x --version
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use `python -m consequa_x` wherever a command below uses `consequa-x`.
|
|
30
|
+
|
|
31
|
+
## See it in a minute
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
consequa-x demo --output my-demo
|
|
35
|
+
consequa-x report my-demo/traces/episode_01.json --output my-report.html
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`demo` writes twelve synthetic refund scenarios with simulated money: timeouts
|
|
39
|
+
before and after commit, false success, partial and duplicate effects, delayed
|
|
40
|
+
readback, retries, another actor and missing provenance. Episode 1 is a timeout
|
|
41
|
+
after commit: the tool timed out and the agent reported failure, but readback
|
|
42
|
+
shows the refund committed and linked to the agent's action. Open
|
|
43
|
+
`my-report.html` in any browser. It is one self-contained file with no scripts
|
|
44
|
+
or network requests.
|
|
45
|
+
|
|
46
|
+
Each run needs a new output directory, and a report never overwrites an existing
|
|
47
|
+
file. The demo's `evaluator_truth/` folder is simulator ground truth for
|
|
48
|
+
evaluation only; never pass it to an explainer.
|
|
49
|
+
|
|
50
|
+
## Use it in Python
|
|
51
|
+
|
|
52
|
+
Register the intended outcome before the action, capture what happened, read the
|
|
53
|
+
outcome back from a trusted read-only source, then verify and explain:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from consequa_x import (
|
|
57
|
+
Action, AgentAssessment, AssessmentStatus, Observation, OutcomeContract,
|
|
58
|
+
Trace, explain, render_report, verify,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
expected = {"payment_id": "p1", "amount_minor": 1000, "currency": "INR"}
|
|
62
|
+
contract = OutcomeContract("contract-1", "refund_processed", expected,
|
|
63
|
+
deadline_ms=50, stability_ms=20)
|
|
64
|
+
action = Action("refund-1", "trace-1", "agent", "refund", expected, 0, contract)
|
|
65
|
+
|
|
66
|
+
# In an application, capture this independently from a trusted read-only source.
|
|
67
|
+
observation = Observation(
|
|
68
|
+
"readback-1", "independent-ledger", 100, 100, {"payment_id": "p1"},
|
|
69
|
+
({**expected, "effect_id": "effect-1", "committed_at_ms": 25,
|
|
70
|
+
"status": "processed", "action_id": "refund-1", "actor": "agent"},),
|
|
71
|
+
)
|
|
72
|
+
receipt = verify(action, observation)
|
|
73
|
+
trace = Trace("trace-1", action, (), (),
|
|
74
|
+
AgentAssessment(AssessmentStatus.FAILURE, 10),
|
|
75
|
+
(observation,), (receipt,))
|
|
76
|
+
|
|
77
|
+
assert receipt.status.value == "satisfied" # the refund really happened
|
|
78
|
+
assert receipt.origin.value == "confirmed" # and this action produced it
|
|
79
|
+
assert explain(trace).assessment_alignment == "contradicted" # the agent said failure
|
|
80
|
+
html = render_report(trace) # offline, minimal disclosure
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The built-in `refund_processed` verifier checks payment, integer amount,
|
|
84
|
+
currency, exact count, commit deadline and a persistence window. Unavailable,
|
|
85
|
+
incomplete, wrongly scoped or stale readback produces `unknown`. Effect origin is
|
|
86
|
+
a separate conclusion: `confirmed`, `other_actor` or `unknown`.
|
|
87
|
+
|
|
88
|
+
Traces round-trip through a portable, versioned JSON schema (`0.1`):
|
|
89
|
+
`Trace.from_json(trace.to_json())` rejects unknown fields, broken identity links
|
|
90
|
+
and dependency cycles. `consequa_x.schema.get_trace_schema()` returns the bundled
|
|
91
|
+
JSON Schema.
|
|
92
|
+
|
|
93
|
+
## Capture a real agent's tool call
|
|
94
|
+
|
|
95
|
+
`TraceRecorder` records an action while your agent runs, and `RecordVerifier`
|
|
96
|
+
checks any outcome that leaves records behind (rows, orders, tickets, files):
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from consequa_x import OutcomeContract, RecordVerifier, TraceRecorder, explain
|
|
100
|
+
|
|
101
|
+
contract = OutcomeContract("refund-o-17", "record_present",
|
|
102
|
+
{"order_id": "o-17", "amount_minor": 5000, "currency": "INR"},
|
|
103
|
+
deadline_ms=200, stability_ms=50)
|
|
104
|
+
verifier = RecordVerifier(scope_fields=("order_id",))
|
|
105
|
+
|
|
106
|
+
rec = TraceRecorder("run-17", actor="support-agent")
|
|
107
|
+
rec.register("refund-o-17", "issue_refund", {"order_id": "o-17"}, contract=contract)
|
|
108
|
+
try:
|
|
109
|
+
with rec.attempt(data={"tool": "issue_refund"}) as attempt:
|
|
110
|
+
issue_refund("o-17", attempt_id=attempt.attempt_id) # your tool
|
|
111
|
+
rec.assessment("success") # what the agent reported
|
|
112
|
+
except TimeoutError:
|
|
113
|
+
rec.assessment("failure")
|
|
114
|
+
rec.verify(read_refunds_for("o-17"), verifier=verifier) # your read-only readback
|
|
115
|
+
print(explain(rec.trace(), target_matcher=verifier.target_matcher()).diagnoses)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`capture_tool` decorates a synchronous tool so every call is recorded the same
|
|
119
|
+
way. The
|
|
120
|
+
[agent-loop example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/agent_loop_sqlite.py)
|
|
121
|
+
runs this end to end against a real SQLite database, offline, in three modes:
|
|
122
|
+
a timeout after the refund committed, a refund made by someone else, and a
|
|
123
|
+
readback too stale to decide.
|
|
124
|
+
|
|
125
|
+
## Bring your own domain
|
|
126
|
+
|
|
127
|
+
Supply a read-only `Verifier` for your predicate, and a `TargetMatcher` when the
|
|
128
|
+
agent's reported success or failure should be judged against that contract:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
receipt = verify(action, observation, verifier=MyVerifier())
|
|
132
|
+
explanation = explain(trace, target_matcher=MyTargetMatcher())
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Your application owns source trust, scope, completeness, timing and provenance;
|
|
136
|
+
Consequa-X checks that receipts bind to the supplied contract and observation,
|
|
137
|
+
and keeps the evidence structured. The
|
|
138
|
+
[artifact-delivery example](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/examples/artifact_delivery.py)
|
|
139
|
+
implements both adapters with public APIs only, and the
|
|
140
|
+
[integration guide](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/application-integration.md)
|
|
141
|
+
describes the boundary in detail. The
|
|
142
|
+
[stable API](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/stable-api.md)
|
|
143
|
+
page lists what version 1 guarantees.
|
|
144
|
+
|
|
145
|
+
## Command line
|
|
146
|
+
|
|
147
|
+
| Command | What it does |
|
|
148
|
+
| --- | --- |
|
|
149
|
+
| `consequa-x demo --output DIR` | Write the twelve synthetic refund scenarios: traces, explanations, schema and manifest |
|
|
150
|
+
| `consequa-x explain TRACE [--output FILE]` | Explain an existing trace without replay; prints JSON or writes a new file |
|
|
151
|
+
| `consequa-x report TRACE --output FILE` | Render a self-contained HTML report; add `--include-details` to embed the full capture |
|
|
152
|
+
| `consequa-x experiment …` and research commands | Paired replay, decision attribution and calibration studies (see Research) |
|
|
153
|
+
|
|
154
|
+
## What it does not do
|
|
155
|
+
|
|
156
|
+
- It does not watch or control a live agent; your application captures the records.
|
|
157
|
+
- It does not authenticate a readback source or prove that provider metadata is true.
|
|
158
|
+
- An evidence-graph link records provenance, not causal necessity.
|
|
159
|
+
- Default reports omit captured strings and identifiers, but keep times, counts
|
|
160
|
+
and relationships. That is field omission, not anonymization.
|
|
161
|
+
- No accuracy advantage over other methods is claimed.
|
|
162
|
+
|
|
163
|
+
## Research
|
|
164
|
+
|
|
165
|
+
The repository also contains declared research interfaces, separate from the
|
|
166
|
+
stable core: isolated replay, contrastive and Shapley-style decision attribution,
|
|
167
|
+
calibration studies, an optional local Ollama adapter, and the retained evidence
|
|
168
|
+
for each study. Results so far are synthetic or exploratory local-model studies
|
|
169
|
+
and are reported with their denominators and limits. Start with the
|
|
170
|
+
[research roadmap](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/docs/research-roadmap.md)
|
|
171
|
+
and the [paper notes](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/paper/README.md).
|
|
172
|
+
|
|
173
|
+
## Platforms
|
|
174
|
+
|
|
175
|
+
The package is pure Python. Released wheels have been install-tested on Windows
|
|
176
|
+
with Python 3.11 and 3.12 and on one Alpine Linux virtual machine with Python
|
|
177
|
+
3.14. macOS has not been tested yet. See the
|
|
178
|
+
[release notes](https://consequa-x.onrender.com/changelog.html) for exact
|
|
179
|
+
environments.
|
|
180
|
+
|
|
181
|
+
## Contributing and support
|
|
182
|
+
|
|
183
|
+
- Questions and bugs: [GitHub issues](https://github.com/Devrajsinh-Jhala/consequa-x/issues/new/choose).
|
|
184
|
+
Use synthetic data only; never post real traces, customer data or credentials.
|
|
185
|
+
- Security: report vulnerabilities privately as described in
|
|
186
|
+
[SECURITY.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/SECURITY.md).
|
|
187
|
+
- Development: see [CONTRIBUTING.md](https://github.com/Devrajsinh-Jhala/consequa-x/blob/main/CONTRIBUTING.md).
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
python -m pip install -e ".[dev]"
|
|
191
|
+
python -m pytest
|
|
192
|
+
python -m ruff check src tests scripts
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT, copyright Devrajsinh Jhala. The website's self-hosted fonts keep their SIL
|
|
198
|
+
Open Font License.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
Please report suspected package vulnerabilities privately through
|
|
4
|
+
[GitHub's private vulnerability reporting form](https://github.com/Devrajsinh-Jhala/consequa-x/security/advisories/new).
|
|
5
|
+
A GitHub account is required. Do not open a public issue containing an exploit,
|
|
6
|
+
credential, private trace or customer data. Use a synthetic reproduction and
|
|
7
|
+
include package/Python/OS versions, impact and reproduction steps. Do not send
|
|
8
|
+
working production credentials.
|
|
9
|
+
|
|
10
|
+
The latest stable release is the primary maintenance target. Version 1 core
|
|
11
|
+
and schema compatibility are documented; no response deadline or long-term
|
|
12
|
+
support period is promised. Security fixes and breaking changes will be stated
|
|
13
|
+
in release notes. Research interfaces can evolve under their declared scope.
|
|
14
|
+
|
|
15
|
+
Default HTML reports omit arbitrary captured fields. They retain timing, counts
|
|
16
|
+
and relationships and do not guarantee anonymity. --include-details explicitly
|
|
17
|
+
includes the entire captured trace as escaped text. Keep those reports private
|
|
18
|
+
when the trace is private. The offline renderer makes no network calls and
|
|
19
|
+
does not execute verifiers, replay or application writes.
|
|
20
|
+
|
|
21
|
+
The framework does not authenticate your readback source or validate that a
|
|
22
|
+
provider's metadata is true. Application-owned adapters must establish source
|
|
23
|
+
trust and domain semantics. Sharing a report does not replace preserving the
|
|
24
|
+
original trace and source evidence.
|
|
@@ -16,7 +16,27 @@ It does not authenticate a source or prove a predicate's domain semantics.
|
|
|
16
16
|
## Outcome verification
|
|
17
17
|
|
|
18
18
|
`verify(action, observation)` retains the built-in `refund_processed` verifier.
|
|
19
|
-
For
|
|
19
|
+
For an outcome that leaves records behind (rows, orders, tickets, files), start
|
|
20
|
+
with the built-in `RecordVerifier` before writing an adapter. Use the predicate
|
|
21
|
+
`record_present`; `contract.expected` lists the field values a matching record
|
|
22
|
+
must carry, and `scope_fields` names the fields the readback snapshot covers:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
verifier = RecordVerifier(scope_fields=("order_id",))
|
|
26
|
+
receipt = verify(action, observation, verifier=verifier)
|
|
27
|
+
explanation = explain(trace, target_matcher=verifier.target_matcher())
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
It checks the exact or minimum count, the commit deadline and the persistence
|
|
31
|
+
window, and returns `unknown` for unavailable, out-of-scope, incomplete, stale
|
|
32
|
+
or malformed readback. Record identifier, commit time, removal time, action,
|
|
33
|
+
actor and attempt field names are configurable; with the defaults the
|
|
34
|
+
evidence graph also links each record to its dispatch.
|
|
35
|
+
|
|
36
|
+
To capture an action while an agent runs, use `TraceRecorder`; see
|
|
37
|
+
[capturing agents built with a framework](framework-integration.md).
|
|
38
|
+
|
|
39
|
+
For any other domain, explicitly supply a read-only adapter:
|
|
20
40
|
|
|
21
41
|
```python
|
|
22
42
|
receipt = verify(action, observation, verifier=application_verifier)
|