poisson-prove 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- poisson_prove-0.1.0/.gitignore +35 -0
- poisson_prove-0.1.0/CHANGELOG.md +73 -0
- poisson_prove-0.1.0/CONTRIBUTING.md +95 -0
- poisson_prove-0.1.0/LICENSE +21 -0
- poisson_prove-0.1.0/NOTICE +38 -0
- poisson_prove-0.1.0/PKG-INFO +316 -0
- poisson_prove-0.1.0/README.md +248 -0
- poisson_prove-0.1.0/docs/architecture.md +65 -0
- poisson_prove-0.1.0/docs/artifact-format.md +286 -0
- poisson_prove-0.1.0/docs/backends.md +152 -0
- poisson_prove-0.1.0/docs/cli-look.md +275 -0
- poisson_prove-0.1.0/docs/commands/check.md +143 -0
- poisson_prove-0.1.0/docs/commands/diff.md +187 -0
- poisson_prove-0.1.0/docs/commands/init.md +128 -0
- poisson_prove-0.1.0/docs/commands/inspect.md +112 -0
- poisson_prove-0.1.0/docs/commands/paired.md +212 -0
- poisson_prove-0.1.0/docs/commands/report.md +196 -0
- poisson_prove-0.1.0/docs/commands/runs.md +90 -0
- poisson_prove-0.1.0/docs/commands/serve.md +162 -0
- poisson_prove-0.1.0/docs/commands/sweep.md +203 -0
- poisson_prove-0.1.0/docs/commands/ui.md +96 -0
- poisson_prove-0.1.0/docs/concepts/censoring-and-competing-risks.md +71 -0
- poisson_prove-0.1.0/docs/concepts/pairing.md +75 -0
- poisson_prove-0.1.0/docs/concepts/the-layered-report.md +85 -0
- poisson_prove-0.1.0/docs/concepts/traces.md +100 -0
- poisson_prove-0.1.0/docs/concepts/what-the-statistics-claim.md +118 -0
- poisson_prove-0.1.0/docs/dashboard.md +92 -0
- poisson_prove-0.1.0/docs/defining-outcomes.md +192 -0
- poisson_prove-0.1.0/docs/fault-injection.md +181 -0
- poisson_prove-0.1.0/docs/python.md +192 -0
- poisson_prove-0.1.0/docs/quickstart.md +118 -0
- poisson_prove-0.1.0/docs/reading-a-serve-page.md +80 -0
- poisson_prove-0.1.0/docs/recipes/a-model-change-with-cost.md +103 -0
- poisson_prove-0.1.0/docs/recipes/a-prompt-change.md +137 -0
- poisson_prove-0.1.0/docs/recipes/first-look.md +90 -0
- poisson_prove-0.1.0/docs/recipes/in-ci.md +87 -0
- poisson_prove-0.1.0/docs/recipes/paired-replay.md +101 -0
- poisson_prove-0.1.0/docs/recipes/when-it-says-too-small-to-tell.md +80 -0
- poisson_prove-0.1.0/docs/repo-hygiene.md +101 -0
- poisson_prove-0.1.0/docs/setup-with-your-agent.md +85 -0
- poisson_prove-0.1.0/docs/sweep-spec.md +214 -0
- poisson_prove-0.1.0/docs/terminal-app.md +111 -0
- poisson_prove-0.1.0/docs/what-capture-stores.md +97 -0
- poisson_prove-0.1.0/docs/with-trace-and-tasks.md +22 -0
- poisson_prove-0.1.0/docs/your-own-agent.md +260 -0
- poisson_prove-0.1.0/examples/your-first-real-agent/README.md +59 -0
- poisson_prove-0.1.0/examples/your-first-real-agent/agent.py +27 -0
- poisson_prove-0.1.0/examples/your-first-real-agent/prove.toml +19 -0
- poisson_prove-0.1.0/pyproject.toml +120 -0
- poisson_prove-0.1.0/src/poisson_prove/__init__.py +16 -0
- poisson_prove-0.1.0/src/poisson_prove/__main__.py +5 -0
- poisson_prove-0.1.0/src/poisson_prove/_banner.py +37 -0
- poisson_prove-0.1.0/src/poisson_prove/_burla_submit.py +287 -0
- poisson_prove-0.1.0/src/poisson_prove/_cli_app.py +894 -0
- poisson_prove-0.1.0/src/poisson_prove/_cli_app_pages.py +1822 -0
- poisson_prove-0.1.0/src/poisson_prove/_compat.py +134 -0
- poisson_prove-0.1.0/src/poisson_prove/_facts.py +318 -0
- poisson_prove-0.1.0/src/poisson_prove/_limits.py +844 -0
- poisson_prove-0.1.0/src/poisson_prove/_look.py +445 -0
- poisson_prove-0.1.0/src/poisson_prove/_names.py +522 -0
- poisson_prove-0.1.0/src/poisson_prove/_render_charts.py +568 -0
- poisson_prove-0.1.0/src/poisson_prove/_render_pretty.py +59 -0
- poisson_prove-0.1.0/src/poisson_prove/_render_term.py +250 -0
- poisson_prove-0.1.0/src/poisson_prove/_render_ui.py +1267 -0
- poisson_prove-0.1.0/src/poisson_prove/_resolve.py +26 -0
- poisson_prove-0.1.0/src/poisson_prove/_ui_bundle/style.css +175 -0
- poisson_prove-0.1.0/src/poisson_prove/_ui_bundle/ui.js +47 -0
- poisson_prove-0.1.0/src/poisson_prove/_verdict.py +807 -0
- poisson_prove-0.1.0/src/poisson_prove/capture.py +589 -0
- poisson_prove-0.1.0/src/poisson_prove/chaos.py +606 -0
- poisson_prove-0.1.0/src/poisson_prove/chaos_catalog.py +145 -0
- poisson_prove-0.1.0/src/poisson_prove/cli.py +2567 -0
- poisson_prove-0.1.0/src/poisson_prove/compare.py +87 -0
- poisson_prove-0.1.0/src/poisson_prove/core/__init__.py +133 -0
- poisson_prove-0.1.0/src/poisson_prove/core/_artifacts.py +513 -0
- poisson_prove-0.1.0/src/poisson_prove/core/_ops.py +2946 -0
- poisson_prove-0.1.0/src/poisson_prove/core/_results.py +557 -0
- poisson_prove-0.1.0/src/poisson_prove/core/_views.py +1614 -0
- poisson_prove-0.1.0/src/poisson_prove/diff.py +2574 -0
- poisson_prove-0.1.0/src/poisson_prove/episode.py +87 -0
- poisson_prove-0.1.0/src/poisson_prove/examples/__init__.py +1 -0
- poisson_prove-0.1.0/src/poisson_prove/examples/mock_agent.py +154 -0
- poisson_prove-0.1.0/src/poisson_prove/examples/quickstart.toml +23 -0
- poisson_prove-0.1.0/src/poisson_prove/executor.py +1295 -0
- poisson_prove-0.1.0/src/poisson_prove/executor_burla.py +1087 -0
- poisson_prove-0.1.0/src/poisson_prove/executor_modal.py +1116 -0
- poisson_prove-0.1.0/src/poisson_prove/otel.py +91 -0
- poisson_prove-0.1.0/src/poisson_prove/paired.py +2643 -0
- poisson_prove-0.1.0/src/poisson_prove/plain.py +209 -0
- poisson_prove-0.1.0/src/poisson_prove/py.typed +0 -0
- poisson_prove-0.1.0/src/poisson_prove/report.py +2710 -0
- poisson_prove-0.1.0/src/poisson_prove/sampler.py +652 -0
- poisson_prove-0.1.0/src/poisson_prove/skills/poisson-prove-setup/SKILL.md +95 -0
- poisson_prove-0.1.0/src/poisson_prove/stats.py +146 -0
- poisson_prove-0.1.0/src/poisson_prove/steps.py +109 -0
- poisson_prove-0.1.0/src/poisson_prove/store.py +899 -0
- poisson_prove-0.1.0/src/poisson_prove/survival.py +292 -0
- poisson_prove-0.1.0/src/poisson_prove/trace.py +1842 -0
- poisson_prove-0.1.0/src/poisson_prove/tree.py +2229 -0
- poisson_prove-0.1.0/src/poisson_prove/viewer.py +1570 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/comparison-120x40.txt +81 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/comparison-80x24.txt +49 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/condition-120x40.txt +81 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/conditions-120x40.txt +81 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/could-not-detect-80x24.txt +49 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/help-80x24.txt +49 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/home-120x40.txt +81 -0
- poisson_prove-0.1.0/tests/__snapshots__/pf6/home-80x24.txt +49 -0
- poisson_prove-0.1.0/tests/bu_fixtures/burla/__init__.py +20 -0
- poisson_prove-0.1.0/tests/bu_fixtures/burla/_env_scan.py +222 -0
- poisson_prove-0.1.0/tests/bu_fixtures/burla/_fake.py +138 -0
- poisson_prove-0.1.0/tests/bu_fixtures/burla/_node.py +75 -0
- poisson_prove-0.1.0/tests/bu_fixtures/burla/_remote_parallel_map.py +487 -0
- poisson_prove-0.1.0/tests/bu_fixtures/deaf_launcher.py +40 -0
- poisson_prove-0.1.0/tests/bu_fixtures/keep_bundle.py +52 -0
- poisson_prove-0.1.0/tests/bu_fixtures/launch.py +89 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_helper/__init__.py +3 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/__init__.py +37 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/blas.py +28 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/data/table.json +1 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/drifting.py +12 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/hostonly.py +14 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/plain.py +18 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/probe.py +52 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/uses_helper.py +11 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_targets/view.py +32 -0
- poisson_prove-0.1.0/tests/bu_fixtures/targets/bu_version/__init__.py +12 -0
- poisson_prove-0.1.0/tests/bu_fixtures/worker.py +135 -0
- poisson_prove-0.1.0/tests/conftest.py +643 -0
- poisson_prove-0.1.0/tests/fixtures/cli-look/README.md +22 -0
- poisson_prove-0.1.0/tests/fixtures/cli-look/bfe802d.md +89 -0
- poisson_prove-0.1.0/tests/fixtures/cli-look/changes.json +23 -0
- poisson_prove-0.1.0/tests/fixtures/pf12/README.md +11 -0
- poisson_prove-0.1.0/tests/fixtures/pf12/look-static-ui.md +60 -0
- poisson_prove-0.1.0/tests/fixtures/run-names/trace-410cfd0.json +635 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/expected/prove.toml +23 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/expected/prove_rollout.py +19 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/sample-repo/README.md +12 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/sample-repo/support_agent/__init__.py +1 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/sample-repo/support_agent/agent.py +49 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/sample-repo/support_agent/cases.py +10 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/sample-repo/support_agent/client.py +31 -0
- poisson_prove-0.1.0/tests/fixtures/setup-agent/setup-file-format-1.txt +50 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/README.md +41 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/SHA256SUMS +44 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/diff-fisher_bh.json +1853 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/diff-mcnemar_bh.json +1853 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-fisher_bh/heatmap.svg +173 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-fisher_bh/receipt.html +222 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-fisher_bh/report.md +144 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-mcnemar_bh/heatmap.svg +173 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-mcnemar_bh/receipt.html +222 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/report-mcnemar_bh/report.md +144 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/serve-fisher_bh.json +2638 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/recorded/serve-mcnemar_bh.json +2638 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/runs.json +9 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00001.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00002.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00003.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00004.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00005.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00006.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00007.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00008.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00009.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00010.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00011.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00012.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00013.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/episodes/part-00014.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035339Z-1add/manifest.json +73 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00001.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00002.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00003.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00004.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00005.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00006.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00007.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00008.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00009.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00010.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00011.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00012.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00013.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/episodes/part-00014.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035345Z-8381/manifest.json +73 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035351Z-56a5/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035351Z-56a5/manifest.json +55 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035403Z-a08e/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035403Z-a08e/manifest.json +52 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035406Z-236f/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035406Z-236f/manifest.json +63 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035409Z-a701/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035409Z-a701/manifest.json +57 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035440Z-1f32/episodes/part-00000.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035440Z-1f32/episodes/part-00001.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035440Z-1f32/episodes/part-00002.parquet +0 -0
- poisson_prove-0.1.0/tests/fixtures/stores-0.0.1/store/20261014T035440Z-1f32/manifest.json +72 -0
- poisson_prove-0.1.0/tests/fixtures/trace/README.md +41 -0
- poisson_prove-0.1.0/tests/fixtures/trace/litellm_calls.json +103 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_agent_chat.json +151 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_aliases.json +60 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_cut.json +82 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_dropped.json +76 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_encodings.json +122 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_kinds.json +263 -0
- poisson_prove-0.1.0/tests/fixtures/trace/otlp_loop.json +516 -0
- poisson_prove-0.1.0/tests/isolated_support.py +89 -0
- poisson_prove-0.1.0/tests/lattice.py +544 -0
- poisson_prove-0.1.0/tests/live/proofload_live_rollout/__init__.py +23 -0
- poisson_prove-0.1.0/tests/live/test_m3_modal_live.py +145 -0
- poisson_prove-0.1.0/tests/pf12_support.py +989 -0
- poisson_prove-0.1.0/tests/pf6_support.py +1436 -0
- poisson_prove-0.1.0/tests/pf7_docs_check.py +791 -0
- poisson_prove-0.1.0/tests/replay_arms.py +124 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/chart.html +24 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/comparison.html +39 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/condition.html +32 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/could-not-detect.html +24 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/episodes.html +23 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/run.html +27 -0
- poisson_prove-0.1.0/tests/snapshots/pf12/runs.html +24 -0
- poisson_prove-0.1.0/tests/test_a10_declared.py +1402 -0
- poisson_prove-0.1.0/tests/test_a22_pandas3.py +358 -0
- poisson_prove-0.1.0/tests/test_a28_agreement.py +587 -0
- poisson_prove-0.1.0/tests/test_a7_storage.py +1658 -0
- poisson_prove-0.1.0/tests/test_a8a_span_schema.py +703 -0
- poisson_prove-0.1.0/tests/test_a8b_cut_and_cap.py +764 -0
- poisson_prove-0.1.0/tests/test_app_banner.py +82 -0
- poisson_prove-0.1.0/tests/test_backend_tests_reach_the_network.py +53 -0
- poisson_prove-0.1.0/tests/test_bu_burla_backend.py +1951 -0
- poisson_prove-0.1.0/tests/test_capture_crash_and_timeout_behaviour.py +371 -0
- poisson_prove-0.1.0/tests/test_cd_cap_declaration.py +815 -0
- poisson_prove-0.1.0/tests/test_competing_set.py +1112 -0
- poisson_prove-0.1.0/tests/test_cut_surfacing.py +797 -0
- poisson_prove-0.1.0/tests/test_defaults_refusals_and_faces.py +448 -0
- poisson_prove-0.1.0/tests/test_fr_first_run.py +1539 -0
- poisson_prove-0.1.0/tests/test_ls_local_serve.py +2382 -0
- poisson_prove-0.1.0/tests/test_m10_cli.py +1404 -0
- poisson_prove-0.1.0/tests/test_m10_multi.py +946 -0
- poisson_prove-0.1.0/tests/test_m11a_chaos.py +1304 -0
- poisson_prove-0.1.0/tests/test_m12_kinds.py +157 -0
- poisson_prove-0.1.0/tests/test_m12_stamper.py +228 -0
- poisson_prove-0.1.0/tests/test_m12_trace.py +1446 -0
- poisson_prove-0.1.0/tests/test_m13_viewer.py +1661 -0
- poisson_prove-0.1.0/tests/test_m1_episode.py +84 -0
- poisson_prove-0.1.0/tests/test_m2_sampler.py +574 -0
- poisson_prove-0.1.0/tests/test_m3_capture.py +1150 -0
- poisson_prove-0.1.0/tests/test_m3_crash_trace.py +788 -0
- poisson_prove-0.1.0/tests/test_m3_local.py +698 -0
- poisson_prove-0.1.0/tests/test_m3_modal.py +925 -0
- poisson_prove-0.1.0/tests/test_m3_modal_launch.py +896 -0
- poisson_prove-0.1.0/tests/test_m3_timeout_trace.py +1064 -0
- poisson_prove-0.1.0/tests/test_m4_read.py +821 -0
- poisson_prove-0.1.0/tests/test_m4_store.py +234 -0
- poisson_prove-0.1.0/tests/test_m5_survival.py +653 -0
- poisson_prove-0.1.0/tests/test_m6_diff.py +827 -0
- poisson_prove-0.1.0/tests/test_m6_multi.py +1383 -0
- poisson_prove-0.1.0/tests/test_m7_multi.py +1979 -0
- poisson_prove-0.1.0/tests/test_m7_report.py +1154 -0
- poisson_prove-0.1.0/tests/test_mc_modal_chaos.py +451 -0
- poisson_prove-0.1.0/tests/test_modal_ctrl_c.py +99 -0
- poisson_prove-0.1.0/tests/test_p1_payload.py +1219 -0
- poisson_prove-0.1.0/tests/test_pf0_name.py +1339 -0
- poisson_prove-0.1.0/tests/test_pf10_ci.py +277 -0
- poisson_prove-0.1.0/tests/test_pf10_worker_blas.py +117 -0
- poisson_prove-0.1.0/tests/test_pf11_setup_agent.py +1321 -0
- poisson_prove-0.1.0/tests/test_pf12_artifacts.py +1053 -0
- poisson_prove-0.1.0/tests/test_pf12_refresh_note.py +68 -0
- poisson_prove-0.1.0/tests/test_pf12_ui.py +1304 -0
- poisson_prove-0.1.0/tests/test_pf1_look.py +1551 -0
- poisson_prove-0.1.0/tests/test_pf2_names.py +1496 -0
- poisson_prove-0.1.0/tests/test_pf3_first_run.py +1029 -0
- poisson_prove-0.1.0/tests/test_pf4_calibration.py +880 -0
- poisson_prove-0.1.0/tests/test_pf4_stats.py +2023 -0
- poisson_prove-0.1.0/tests/test_pf4_surfaces.py +1871 -0
- poisson_prove-0.1.0/tests/test_pf5_api_core.py +1815 -0
- poisson_prove-0.1.0/tests/test_pf5_result_pickle.py +93 -0
- poisson_prove-0.1.0/tests/test_pf6_app.py +1760 -0
- poisson_prove-0.1.0/tests/test_pf6_look.py +746 -0
- poisson_prove-0.1.0/tests/test_pf7_docs.py +1185 -0
- poisson_prove-0.1.0/tests/test_pf7_packaging.py +367 -0
- poisson_prove-0.1.0/tests/test_pf8_public_hygiene.py +1069 -0
- poisson_prove-0.1.0/tests/test_pf9_backends.py +584 -0
- poisson_prove-0.1.0/tests/test_pr1_pair_assertion.py +1526 -0
- poisson_prove-0.1.0/tests/test_pr2_paired_analysis.py +1434 -0
- poisson_prove-0.1.0/tests/test_pr3_pair_exclusion.py +130 -0
- poisson_prove-0.1.0/tests/test_pr3_paired_output.py +1529 -0
- poisson_prove-0.1.0/tests/test_pr3_replicates.py +2029 -0
- poisson_prove-0.1.0/tests/test_s0_scaffold.py +122 -0
- poisson_prove-0.1.0/tests/test_s21_errors.py +2088 -0
- poisson_prove-0.1.0/tests/test_s23_power.py +828 -0
- poisson_prove-0.1.0/tests/test_s24_interval.py +1364 -0
- poisson_prove-0.1.0/tests/test_s25_root.py +1501 -0
- poisson_prove-0.1.0/tests/test_s26_fault_lines.py +1895 -0
- poisson_prove-0.1.0/tests/test_s27_leaves.py +2033 -0
- poisson_prove-0.1.0/tests/test_s28_report.py +2249 -0
- poisson_prove-0.1.0/tests/test_s29_viewer.py +2291 -0
- poisson_prove-0.1.0/tests/test_s3_golden_fixture.py +300 -0
- poisson_prove-0.1.0/tests/test_storage_and_chaos_behaviour.py +455 -0
- poisson_prove-0.1.0/tests/test_stored_trace_read.py +595 -0
- poisson_prove-0.1.0/tests/test_suite_hygiene.py +61 -0
- poisson_prove-0.1.0/tests/test_unpaired_warning.py +337 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
.eggs/
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# Testing / tooling caches
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.hypothesis/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
.coverage
|
|
24
|
+
htmlcov/
|
|
25
|
+
|
|
26
|
+
# Run stores. The default store root is ./prove-runs.
|
|
27
|
+
prove-runs/
|
|
28
|
+
|
|
29
|
+
# A contributor's own working log, never committed
|
|
30
|
+
devlog.md
|
|
31
|
+
|
|
32
|
+
# Editors / OS
|
|
33
|
+
.vscode/
|
|
34
|
+
.idea/
|
|
35
|
+
.DS_Store
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Poisson Prove are written here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
|
|
5
|
+
[semantic versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## 0.1.0 — 2026-10-29
|
|
8
|
+
|
|
9
|
+
The first public release. Prove tells you whether a change to an AI agent really changed how often
|
|
10
|
+
it fails. It replays the same cases before and after the change, on the same seeds, compares the
|
|
11
|
+
two runs condition by condition, and gives a verdict with stated error bounds and detection
|
|
12
|
+
limits. Python 3.11 to 3.14, on macOS and Linux.
|
|
13
|
+
|
|
14
|
+
### Verbs
|
|
15
|
+
|
|
16
|
+
- `poisson-prove init` writes `prove.toml`, a sweep spec to edit; `init --example` writes the
|
|
17
|
+
keyless example; `init --agent` writes a skill and a prompt for your own coding agent, which sets
|
|
18
|
+
Prove up in your repository for you to review. Prove itself makes no model call.
|
|
19
|
+
- `poisson-prove sweep` prints the plan, its cost and the smallest change one condition alone would
|
|
20
|
+
be flagged for, refuses a design too small for the change you accept and names the replicates
|
|
21
|
+
that would do, then runs the sweep on this machine, on Modal or on Burla. A stopped sweep resumes
|
|
22
|
+
where it stopped, and `--pair-with` gives a sweep an earlier run's seeds.
|
|
23
|
+
- `poisson-prove diff` compares two stored runs condition by condition, per outcome, and names the
|
|
24
|
+
method it used.
|
|
25
|
+
- `poisson-prove report` writes `report.md`, `heatmap.svg` and `receipt.html` for two runs, or one,
|
|
26
|
+
and saves the comparison.
|
|
27
|
+
- `poisson-prove paired` checks that a declaration's arms replayed the same requests, then writes
|
|
28
|
+
its files.
|
|
29
|
+
- `poisson-prove check` gates on a comparison: passed exits 0, failed exits 4.
|
|
30
|
+
- `poisson-prove serve` serves a read-only page comparing two runs on a loopback port, and saves
|
|
31
|
+
the comparison.
|
|
32
|
+
- `poisson-prove inspect` prints the episodes behind an outcome, with a snippet to reproduce one.
|
|
33
|
+
- `poisson-prove runs` lists the runs in the store, by name and id.
|
|
34
|
+
- `poisson-prove ui` builds the dashboard: static pages over the store, opened from disk.
|
|
35
|
+
- `poisson-prove` with no verb, on a terminal, opens the terminal app over the store.
|
|
36
|
+
|
|
37
|
+
### Concepts
|
|
38
|
+
|
|
39
|
+
- The verdict is one word for the whole comparison: `safer`, `worse`, `trade` (some conditions
|
|
40
|
+
safer and at least one worse), `no significant change` (no change counted, and every condition
|
|
41
|
+
could have caught one of the size you accepted) or `too small to tell` (no change counted, and at
|
|
42
|
+
least one condition could not have).
|
|
43
|
+
- A condition's flag is held to a false discovery rate (Benjamini-Hochberg); the verdict counts
|
|
44
|
+
only the changes that also hold at the family-wise level (Holm).
|
|
45
|
+
- Every condition that did not move says how large a change it would have caught 4 times in 5,
|
|
46
|
+
computed for the test the comparison used, or that it could not have caught one at all.
|
|
47
|
+
- Runs paired at sweep time share their seeds and are compared with the paired test (McNemar) by
|
|
48
|
+
default; every output names the method it used.
|
|
49
|
+
- Every episode is stored in Parquet with its seed, outcome, time and trace. Runs go by readable
|
|
50
|
+
names, and `latest` and `previous` stand for the two newest.
|
|
51
|
+
- Runs and saved comparisons are written in a documented artifact format, which the dashboard and
|
|
52
|
+
the terminal app read.
|
|
53
|
+
- The layered report: one omnibus test over every condition, the fault lines that group them, and
|
|
54
|
+
the conditions under each.
|
|
55
|
+
- Fault injection through a `[chaos]` table, and capture of an agent's trace through OpenTelemetry.
|
|
56
|
+
- A Modal or Burla worker runs the rollout's BLAS on one thread unless its environment sets a
|
|
57
|
+
thread count; `threadpoolctl` is a core requirement for this.
|
|
58
|
+
- The Python API (`poisson_prove`) gives the same comparisons the command line prints.
|
|
59
|
+
- The packaged example needs no key: a mock agent and a patched version of it, swept on the same
|
|
60
|
+
seeds, whose comparison reads `trade`.
|
|
61
|
+
|
|
62
|
+
### Install
|
|
63
|
+
|
|
64
|
+
- `pip install poisson-prove`. The extras are `[modal]` (Modal 1.0.0 or later), `[burla]`
|
|
65
|
+
(exactly Burla 1.8.2; the backend is experimental), `[agent]` (OpenTelemetry capture and the
|
|
66
|
+
OpenAI client), and `[all]`.
|
|
67
|
+
- Prove sends nothing anywhere beyond the backend you choose: no telemetry, no analytics, no update
|
|
68
|
+
check. `serve` binds to 127.0.0.1 only.
|
|
69
|
+
|
|
70
|
+
### Renamed
|
|
71
|
+
|
|
72
|
+
- This is the first public release. Earlier private builds were called proofload; stores they
|
|
73
|
+
wrote are read unchanged.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for helping. This page says how to set up a checkout, run the tests, and send a change.
|
|
4
|
+
[Architecture](https://github.com/poisson-labs/prove/blob/main/docs/architecture.md) says where a
|
|
5
|
+
change belongs.
|
|
6
|
+
|
|
7
|
+
## Set up
|
|
8
|
+
|
|
9
|
+
Prove needs Python 3.11 or later. Install the checkout with every extra and the development tools,
|
|
10
|
+
in a virtual environment of its own:
|
|
11
|
+
|
|
12
|
+
<!-- docs-check: skip: installs a checkout for development, run from its root -->
|
|
13
|
+
```bash
|
|
14
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
15
|
+
pip install -e ".[all,dev]"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Running the tests
|
|
19
|
+
|
|
20
|
+
Two suites. Run the code suite before every pull request, and the math suite (the statistics,
|
|
21
|
+
marked `math`) when you change statistics code:
|
|
22
|
+
|
|
23
|
+
<!-- docs-check: skip: runs the test suites of a checkout -->
|
|
24
|
+
```bash
|
|
25
|
+
python -m pytest tests -n 10 -m "not math and not calibration and not backend and not slow"
|
|
26
|
+
python -m pytest tests -n 10 -m math
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`-n` runs the tests in parallel (`pytest-xdist`); pick a number near your machine's cores. The code
|
|
30
|
+
suite takes a few minutes. Tests marked `calibration` are the slow statistical checks of the error
|
|
31
|
+
rates; tests marked `backend` call a real Modal or Burla account and never run unless you opt in.
|
|
32
|
+
|
|
33
|
+
Tests marked `slow` take longer and some reach the package index: a browser check of the
|
|
34
|
+
dashboard's pages, every docs page run again from the built wheel in a fresh environment, and the
|
|
35
|
+
code suite with every requirement installed at its stated floor on Python 3.11. At the floors,
|
|
36
|
+
numpy and SciPy each start a BLAS thread pool in every process, so set `OPENBLAS_NUM_THREADS=1`
|
|
37
|
+
for this run or the parallel workers swamp the machine. The browser check needs Playwright's
|
|
38
|
+
engines:
|
|
39
|
+
|
|
40
|
+
<!-- docs-check: skip: runs the slow tests of a checkout -->
|
|
41
|
+
```bash
|
|
42
|
+
python -m playwright install chromium firefox webkit
|
|
43
|
+
OPENBLAS_NUM_THREADS=1 python -m pytest tests -n 6 -m "slow and not backend"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## CI
|
|
47
|
+
|
|
48
|
+
Every pull request and every push to main runs the code lane: ruff, the format check on `src`,
|
|
49
|
+
mypy and the code suite, on Python 3.11 for a pull request and on 3.11 and 3.14 for main. A pull request that changes the statistics, a test
|
|
50
|
+
of the math suite, or the version a statistics library resolves to also runs the math suite, and the
|
|
51
|
+
job summary says why. Every night, and before a release, CI runs everything else: the code suite on
|
|
52
|
+
every supported Python, the math suite, the slow tests, the floors run and the code suite in a Linux
|
|
53
|
+
container. Tests marked `backend` never run in CI. Each job's summary gives the tests it ran, its
|
|
54
|
+
time against the lane's budget, and the code lane's tests over 10 seconds.
|
|
55
|
+
|
|
56
|
+
## The docs are tested
|
|
57
|
+
|
|
58
|
+
Every command block in the README and under `docs/` runs, from a folder of its own, and must do
|
|
59
|
+
what its page shows: each block carries a mark in an HTML comment on the line before it
|
|
60
|
+
(`run`, `skip: REASON`, or `file NAME`), and a block with no mark fails. A page's shown output is
|
|
61
|
+
checked by its verdict word and its line labels, never by its counts, which change from one sweep
|
|
62
|
+
to the next. The docs check under `tests/` defines the marks in its docstring. When you change a
|
|
63
|
+
command's output or its help, run the docs tests and update the pages they name.
|
|
64
|
+
|
|
65
|
+
## Snapshots
|
|
66
|
+
|
|
67
|
+
A few tests compare a page of the dashboard whole against a snapshot under `tests/snapshots/`,
|
|
68
|
+
and a screen of the terminal app whole (its rows and each cell's colour role) against one under
|
|
69
|
+
`tests/__snapshots__/`. They are the one place output is pinned whole; everywhere else a test pins
|
|
70
|
+
facts. When a change to a page or a screen is meant, rewrite the snapshots with the one command
|
|
71
|
+
that does so and review the diff in the pull request:
|
|
72
|
+
|
|
73
|
+
<!-- docs-check: skip: rewrites the snapshots of a checkout -->
|
|
74
|
+
```bash
|
|
75
|
+
python -m pytest tests -k snapshot --update-snapshots
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Rules the code keeps
|
|
79
|
+
|
|
80
|
+
- The core imports no network library and no optional package: `modal`, `burla`, `openai` and the
|
|
81
|
+
OpenTelemetry SDK live behind their extras, and a bare install runs every verb locally.
|
|
82
|
+
- Prove makes no network call of its own: no telemetry, no update check. `serve` binds 127.0.0.1
|
|
83
|
+
only.
|
|
84
|
+
- A test pins a fact, never prose. A test is changed only by a commit that says why, never to make
|
|
85
|
+
a change pass.
|
|
86
|
+
- Frozen tests are read-only. A test written before the code it checks is not edited, skipped or
|
|
87
|
+
marked to fail so that a change passes; if one looks wrong, say so in the pull request.
|
|
88
|
+
- Every requirement has a floor that the slow floors test installs and runs; raise one only with
|
|
89
|
+
the reason in the commit.
|
|
90
|
+
|
|
91
|
+
## Sending a change
|
|
92
|
+
|
|
93
|
+
Commits are signed and their messages follow Conventional Commits (`feat:`, `fix:`, `docs:`,
|
|
94
|
+
`test:`, `chore:`), each saying in plain words what changed and why. One pull request per change,
|
|
95
|
+
with the tests that pin it, the docs it moves, and the suites green.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Taylor Kolasinski / Poisson Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Poisson Prove
|
|
2
|
+
Copyright (c) 2026 Taylor Kolasinski / Poisson Labs
|
|
3
|
+
|
|
4
|
+
This product includes data from a third party, listed below. Poisson Prove itself is
|
|
5
|
+
distributed under the MIT licence; see LICENSE.
|
|
6
|
+
|
|
7
|
+
--------------------------------------------------------------------------------
|
|
8
|
+
AgentChaos
|
|
9
|
+
https://github.com/floritange/AgentChaos
|
|
10
|
+
Distributed on PyPI as the agentchaos-sdk distribution, version 0.1.0
|
|
11
|
+
Licence: MIT
|
|
12
|
+
|
|
13
|
+
src/poisson_prove/chaos_catalog.py carries a copy of AgentChaos's fault vocabulary: the
|
|
14
|
+
fault names, their target paths and their literal replacement strings, read from
|
|
15
|
+
agentchaos/fault_config.py of the 0.1.0 wheel. No AgentChaos code is included and
|
|
16
|
+
AgentChaos is not a dependency of Prove at any tier; the mutation semantics behind the
|
|
17
|
+
copied names are Prove's own.
|
|
18
|
+
|
|
19
|
+
MIT License
|
|
20
|
+
|
|
21
|
+
Copyright (c) 2025 AgentChaos contributors
|
|
22
|
+
|
|
23
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
24
|
+
software and associated documentation files (the "Software"), to deal in the Software
|
|
25
|
+
without restriction, including without limitation the rights to use, copy, modify,
|
|
26
|
+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
27
|
+
permit persons to whom the Software is furnished to do so, subject to the following
|
|
28
|
+
conditions:
|
|
29
|
+
|
|
30
|
+
The above copyright notice and this permission notice shall be included in all copies
|
|
31
|
+
or substantial portions of the Software.
|
|
32
|
+
|
|
33
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
34
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
35
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
36
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
37
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
38
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: poisson-prove
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Did your change to the agent really change how often it fails? Replays the same cases before and after, and says per condition, with stated error bounds and detection limits.
|
|
5
|
+
Project-URL: Homepage, https://poissonlabs.ai/tools/prove
|
|
6
|
+
Project-URL: Source, https://github.com/poisson-labs/prove
|
|
7
|
+
Project-URL: Documentation, https://github.com/poisson-labs/prove/tree/main/docs
|
|
8
|
+
Project-URL: Changelog, https://github.com/poisson-labs/prove/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Issues, https://github.com/poisson-labs/prove/issues
|
|
10
|
+
Author-email: Poisson Labs <work@poissonlabs.ai>
|
|
11
|
+
Maintainer-email: Poisson Labs <work@poissonlabs.ai>
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: NOTICE
|
|
15
|
+
Keywords: agents,evaluation,llm,reliability,statistics,testing
|
|
16
|
+
Classifier: Development Status :: 3 - Alpha
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: Operating System :: MacOS
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
28
|
+
Classifier: Topic :: Software Development :: Testing
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
|
+
Requires-Dist: numpy>=1.24.0
|
|
32
|
+
Requires-Dist: pandas>=2.0.0
|
|
33
|
+
Requires-Dist: pyarrow>=17.0.0
|
|
34
|
+
Requires-Dist: rich>=14.2.0
|
|
35
|
+
Requires-Dist: scipy>=1.10.0
|
|
36
|
+
Requires-Dist: textual>=6.4.0
|
|
37
|
+
Requires-Dist: threadpoolctl>=3.0.0
|
|
38
|
+
Provides-Extra: agent
|
|
39
|
+
Requires-Dist: openai<3,>=2.20; extra == 'agent'
|
|
40
|
+
Requires-Dist: opentelemetry-sdk>=1.41.0; extra == 'agent'
|
|
41
|
+
Provides-Extra: all
|
|
42
|
+
Requires-Dist: burla==1.8.2; extra == 'all'
|
|
43
|
+
Requires-Dist: modal>=1.0.0; extra == 'all'
|
|
44
|
+
Requires-Dist: openai<3,>=2.20; extra == 'all'
|
|
45
|
+
Requires-Dist: opentelemetry-sdk>=1.41.0; extra == 'all'
|
|
46
|
+
Provides-Extra: burla
|
|
47
|
+
Requires-Dist: burla==1.8.2; extra == 'burla'
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: cloudpickle>=3.1.1; extra == 'dev'
|
|
50
|
+
Requires-Dist: hatchling>=1.27.0; extra == 'dev'
|
|
51
|
+
Requires-Dist: hypothesis>=6.70.0; extra == 'dev'
|
|
52
|
+
Requires-Dist: jsonschema>=4.18.0; extra == 'dev'
|
|
53
|
+
Requires-Dist: lifelines>=0.27.8; extra == 'dev'
|
|
54
|
+
Requires-Dist: markdown-it-py>=2.2.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: mypy>=2.2.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-common>=1.41.0; extra == 'dev'
|
|
57
|
+
Requires-Dist: packaging>=25.0; extra == 'dev'
|
|
58
|
+
Requires-Dist: playwright>=1.40.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: pyte>=0.8.1; extra == 'dev'
|
|
60
|
+
Requires-Dist: pytest-xdist>=3.5.0; extra == 'dev'
|
|
61
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
62
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'dev'
|
|
63
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
64
|
+
Requires-Dist: statsmodels>=0.14.0; extra == 'dev'
|
|
65
|
+
Provides-Extra: modal
|
|
66
|
+
Requires-Dist: modal>=1.0.0; extra == 'modal'
|
|
67
|
+
Description-Content-Type: text/markdown
|
|
68
|
+
|
|
69
|
+
# Poisson Prove
|
|
70
|
+
|
|
71
|
+
Did your change to the agent really change how often it fails?
|
|
72
|
+
|
|
73
|
+
Prove replays the same cases before and after a change, on the same seeds, and tells you per condition
|
|
74
|
+
whether failures went up, went down, or did not move by more than it could have detected, with stated
|
|
75
|
+
error bounds and detection limits. Every verdict comes with the smallest change that condition could
|
|
76
|
+
have shown.
|
|
77
|
+
|
|
78
|
+
<!-- docs-check: run -->
|
|
79
|
+
|
|
80
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
81
|
+
pip install poisson-prove
|
|
82
|
+
poisson-prove init --example
|
|
83
|
+
poisson-prove sweep --yes
|
|
84
|
+
poisson-prove sweep --yes --target poisson_prove.examples.mock_agent:rollout_patched --pair-with latest
|
|
85
|
+
poisson-prove diff
|
|
86
|
+
|
|
87
|
+
- No key and no account for the example; your own agent runs on your machine by default.
|
|
88
|
+
- Prove sends nothing anywhere: no telemetry, no update check; `serve` binds to 127.0.0.1 only.
|
|
89
|
+
- Python 3.11 to 3.14 on macOS and Linux. MIT licensed.
|
|
90
|
+
|
|
91
|
+
For your own agent you write one function that runs one case and says how it ended: see
|
|
92
|
+
[Your own agent](https://github.com/poisson-labs/prove/blob/main/docs/your-own-agent.md).
|
|
93
|
+
`uv tool install poisson-prove` or `pipx install poisson-prove` installs the command alone: enough
|
|
94
|
+
for the example, not for importing your agent.
|
|
95
|
+
|
|
96
|
+
## What the first run showed
|
|
97
|
+
|
|
98
|
+
The example sweeps a small mock agent over three tasks and three tool failure rates, 194 episodes
|
|
99
|
+
in each of the nine conditions, then sweeps a patched version of it (it retries a failed tool call
|
|
100
|
+
once) on the same seeds. `diff` compares the two runs:
|
|
101
|
+
|
|
102
|
+
<!-- docs-check: run -->
|
|
103
|
+
```console
|
|
104
|
+
$ poisson-prove diff
|
|
105
|
+
trade timeout: … safer, … worse · violated: … safer, … worse (paired test on shared seeds); …
|
|
106
|
+
method paired test on shared seeds (McNemar), the default for runs paired at sweep time
|
|
107
|
+
before mock-agent 2026-10-26 a
|
|
108
|
+
after mock-agent 2026-10-26 b
|
|
109
|
+
…
|
|
110
|
+
next: poisson-prove report --x task_id --y tool_fail_rate
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Read the first line word by word. `trade` is the verdict: some conditions got safer and at least
|
|
114
|
+
one got worse. Then, per outcome, how many conditions were flagged as falling (safer) and rising
|
|
115
|
+
(worse); the clause after the test names the changes that also hold at the stricter level the word
|
|
116
|
+
is decided at, where they differ from the flags.
|
|
117
|
+
`violated` (the agent took a forbidden fallback) falls in most conditions and rises in none;
|
|
118
|
+
`timeout` (the agent ran out of its 20 tool calls) falls in some and rises in the hardest one. The
|
|
119
|
+
patch trades one failure for another: retrying keeps the agent off the forbidden path, and where
|
|
120
|
+
tools fail most the retries use up its budget. "Paired test on shared seeds" says the two runs drew
|
|
121
|
+
the same random numbers, so each episode is compared with its twin. The counts move a little from
|
|
122
|
+
one pair of sweeps to the next, since each pair draws fresh seeds; the verdict did not, in our runs.
|
|
123
|
+
|
|
124
|
+
The lines under it name the method and the two runs; the full output goes on, with every
|
|
125
|
+
condition's change, an interval on it and the smallest change it could have detected. The `next:`
|
|
126
|
+
line is the command to run next, whole.
|
|
127
|
+
|
|
128
|
+
## Let your coding agent set it up
|
|
129
|
+
|
|
130
|
+
<!-- docs-check: run -->
|
|
131
|
+
```console
|
|
132
|
+
$ poisson-prove init --agent
|
|
133
|
+
ok wrote the setup for your coding agent (4 files)
|
|
134
|
+
…
|
|
135
|
+
prompt Use the poisson-prove-setup skill in this repository: set Poisson Prove up for me to review, then stop.
|
|
136
|
+
next: give your coding agent the prompt above, then review what it wrote
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This writes a skill your coding agent (Claude Code, Codex, Cursor) follows. Give it the prompt: it
|
|
140
|
+
reads your code, writes `prove_rollout.py` and `prove.toml`, checks them with
|
|
141
|
+
`poisson-prove sweep --dry-run`, and stops for you to review. Prove makes no model call and reads no
|
|
142
|
+
key. When the files look right, run `poisson-prove sweep` yourself. The whole procedure is in
|
|
143
|
+
[Set Prove up with your coding agent](https://github.com/poisson-labs/prove/blob/main/docs/setup-with-your-agent.md).
|
|
144
|
+
|
|
145
|
+
## The terminal app and the dashboard
|
|
146
|
+
|
|
147
|
+
On a terminal, `poisson-prove` with no verb opens the terminal app: your runs, your comparisons and
|
|
148
|
+
their verdicts, a sweep from the folder's `prove.toml`, all by keys. `poisson-prove ui` builds a
|
|
149
|
+
dashboard of the same views as pages you open from disk:
|
|
150
|
+
|
|
151
|
+
<!-- docs-check: run -->
|
|
152
|
+
```console
|
|
153
|
+
$ poisson-prove ui
|
|
154
|
+
ok dashboard at file:///…/prove-runs/.poisson/ui/index.html
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
See [The terminal app](https://github.com/poisson-labs/prove/blob/main/docs/terminal-app.md) and
|
|
158
|
+
[The dashboard](https://github.com/poisson-labs/prove/blob/main/docs/dashboard.md).
|
|
159
|
+
|
|
160
|
+
## Your own agent
|
|
161
|
+
|
|
162
|
+
A rollout is a function `(cfg, seed) -> Episode`: it runs one case of your agent under the
|
|
163
|
+
condition `cfg` names, with randomness seeded from `seed`, and says how the case ended. This one
|
|
164
|
+
wraps a support bot:
|
|
165
|
+
|
|
166
|
+
<!-- docs-check: file my_rollout.py -->
|
|
167
|
+
```python
|
|
168
|
+
from poisson_prove import Episode
|
|
169
|
+
from support_bot import TICKETS, handle # your agent and its cases
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def rollout(cfg, seed):
|
|
173
|
+
ticket = TICKETS[cfg["ticket"]]
|
|
174
|
+
reply = handle(ticket, temperature=cfg["temperature"], seed=seed)
|
|
175
|
+
if reply.timed_out:
|
|
176
|
+
outcome = "timeout"
|
|
177
|
+
elif reply.resolved:
|
|
178
|
+
outcome = "resolved"
|
|
179
|
+
else:
|
|
180
|
+
outcome = "unresolved"
|
|
181
|
+
return Episode(outcome=outcome, t=reply.steps, horizon=20, meta={"case_id": cfg["ticket"]})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The sweep spec names it with `target`, lists the conditions as axes (each case its own axis value,
|
|
185
|
+
so a condition runs one case) and says which outcomes count against the agent:
|
|
186
|
+
|
|
187
|
+
<!-- docs-check: file support.toml -->
|
|
188
|
+
```toml
|
|
189
|
+
target = "my_rollout:rollout"
|
|
190
|
+
target_id = "support-bot"
|
|
191
|
+
t_unit = "steps"
|
|
192
|
+
replicates = 200
|
|
193
|
+
|
|
194
|
+
[axes.ticket]
|
|
195
|
+
type = "categorical"
|
|
196
|
+
values = ["refund", "password", "shipping"]
|
|
197
|
+
|
|
198
|
+
[axes.temperature]
|
|
199
|
+
type = "continuous"
|
|
200
|
+
values = [0.0, 0.7]
|
|
201
|
+
|
|
202
|
+
[declare]
|
|
203
|
+
outcomes = ["resolved", "unresolved", "timeout"]
|
|
204
|
+
failures = ["unresolved", "timeout"]
|
|
205
|
+
successes = ["resolved"]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
An agent traced with OpenTelemetry can have its spans stored with each episode by adding a
|
|
209
|
+
`[capture]` table (it needs `pip install "poisson-prove[agent]"` and the instrumentor you name):
|
|
210
|
+
|
|
211
|
+
<!-- docs-check: run -->
|
|
212
|
+
```toml
|
|
213
|
+
[capture]
|
|
214
|
+
instrument = ["openai"]
|
|
215
|
+
content = false
|
|
216
|
+
max_observation_bytes = 16384
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
[Your own agent](https://github.com/poisson-labs/prove/blob/main/docs/your-own-agent.md) runs this
|
|
220
|
+
example end to end and says what each piece does.
|
|
221
|
+
|
|
222
|
+
## Recipes
|
|
223
|
+
|
|
224
|
+
- [First look](https://github.com/poisson-labs/prove/blob/main/docs/recipes/first-look.md): the example, and how to read every block of `diff`.
|
|
225
|
+
- [A prompt change](https://github.com/poisson-labs/prove/blob/main/docs/recipes/a-prompt-change.md): before and after a change to your prompt, paired, with a gate.
|
|
226
|
+
- [A model change, with its cost](https://github.com/poisson-labs/prove/blob/main/docs/recipes/a-model-change-with-cost.md): a cheaper model as an axis, and what it saves.
|
|
227
|
+
- [In CI](https://github.com/poisson-labs/prove/blob/main/docs/recipes/in-ci.md): `check` as a step that fails the build.
|
|
228
|
+
- [When it says too small to tell](https://github.com/poisson-labs/prove/blob/main/docs/recipes/when-it-says-too-small-to-tell.md): what to change so it can tell.
|
|
229
|
+
- [Paired replay](https://github.com/poisson-labs/prove/blob/main/docs/recipes/paired-replay.md): does the same request, sent twice, get the same decision?
|
|
230
|
+
|
|
231
|
+
## Commands
|
|
232
|
+
|
|
233
|
+
- `init`: write `prove.toml`, the keyless example, or the setup for your coding agent ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/init.md)).
|
|
234
|
+
- `sweep`: show the plan, then run every condition of the spec ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/sweep.md)).
|
|
235
|
+
- `diff`: compare two runs condition by condition ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/diff.md)).
|
|
236
|
+
- `check`: the same comparison as a gate that exits 4 when it fails ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/check.md)).
|
|
237
|
+
- `report`: write a report folder with a heatmap and a receipt ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/report.md)).
|
|
238
|
+
- `paired`: check that two arms replayed the same requests, then analyse them ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/paired.md)).
|
|
239
|
+
- `serve`: one comparison as a page on a loopback port ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/serve.md)).
|
|
240
|
+
- `inspect`: the episodes behind an outcome, with code to reproduce one ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/inspect.md)).
|
|
241
|
+
- `runs`: the runs in the store ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/runs.md)).
|
|
242
|
+
- `ui`: build the dashboard ([page](https://github.com/poisson-labs/prove/blob/main/docs/commands/ui.md)).
|
|
243
|
+
|
|
244
|
+
## What the numbers claim, and what they do not
|
|
245
|
+
|
|
246
|
+
Each condition's change is tested on its own, and the flags are held to a false discovery rate
|
|
247
|
+
(Benjamini-Hochberg, q 0.05 by default); the verdict word counts only the changes that also hold
|
|
248
|
+
at the family-wise level (Holm). Every condition that did not move says how large a change it would
|
|
249
|
+
have caught 4 times in 5. `no significant change` means no change counted and every condition could
|
|
250
|
+
have caught one of the size you accepted; `too small to tell` means at least one could not. Before
|
|
251
|
+
a sweep runs, the plan refuses a design too small to detect the change you accept.
|
|
252
|
+
|
|
253
|
+
What Prove does not claim: that the change caused anything (it compares two runs), anything about
|
|
254
|
+
conditions you did not sweep, or that an outcome label means what you meant by it. It is not a
|
|
255
|
+
benchmark, an agent framework or an observability tool, and it never edits your code. [What the statistics claim](https://github.com/poisson-labs/prove/blob/main/docs/concepts/what-the-statistics-claim.md)
|
|
256
|
+
says it in full, and [Defining outcomes](https://github.com/poisson-labs/prove/blob/main/docs/defining-outcomes.md)
|
|
257
|
+
says how to choose labels that measure your agent and not your provider. The serve page and the
|
|
258
|
+
traces have pages of their own:
|
|
259
|
+
[Reading a serve page](https://github.com/poisson-labs/prove/blob/main/docs/reading-a-serve-page.md) and
|
|
260
|
+
[What capture stores](https://github.com/poisson-labs/prove/blob/main/docs/what-capture-stores.md).
|
|
261
|
+
|
|
262
|
+
## Where Prove sits beside Trace and Tasks
|
|
263
|
+
|
|
264
|
+
Tasks makes the cases; Prove says whether a change moved the failure rate, and by how much it
|
|
265
|
+
could have; Trace says where in a run it failed, and whether that moved. Prove installs alone and
|
|
266
|
+
calls neither; Trace reads Prove's store. See
|
|
267
|
+
[Prove with Trace and Tasks](https://github.com/poisson-labs/prove/blob/main/docs/with-trace-and-tasks.md).
|
|
268
|
+
|
|
269
|
+
## Backends
|
|
270
|
+
|
|
271
|
+
Sweeps run on your machine by default. `--backend modal` runs them in parallel Modal containers on
|
|
272
|
+
your own account (`pip install "poisson-prove[modal]"`), with a cost estimate in the plan.
|
|
273
|
+
`--backend burla` runs them on your own Burla cluster (`pip install "poisson-prove[burla]"`); it is
|
|
274
|
+
experimental. Your rollout's code and conditions go to the account you choose, and the rows come
|
|
275
|
+
back to the same local store. See [Backends](https://github.com/poisson-labs/prove/blob/main/docs/backends.md).
|
|
276
|
+
|
|
277
|
+
Prove never phones home. No telemetry, no analytics, no update checks. `poisson-prove serve` binds a
|
|
278
|
+
loopback listener on request and makes no outbound connection: it holds one page built from data
|
|
279
|
+
already on the machine, and dies with the process.
|
|
280
|
+
|
|
281
|
+
## Python
|
|
282
|
+
|
|
283
|
+
The comparisons, the store and the statistics are importable; `compare.diff` returns the result
|
|
284
|
+
`diff` prints:
|
|
285
|
+
|
|
286
|
+
<!-- docs-check: run -->
|
|
287
|
+
```python
|
|
288
|
+
from poisson_prove import compare
|
|
289
|
+
|
|
290
|
+
for run in compare.runs("prove-runs"):
|
|
291
|
+
print(run.run_name, run.run_id)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
See [Python API](https://github.com/poisson-labs/prove/blob/main/docs/python.md).
|
|
295
|
+
|
|
296
|
+
## Development
|
|
297
|
+
|
|
298
|
+
[CONTRIBUTING.md](https://github.com/poisson-labs/prove/blob/main/CONTRIBUTING.md) says how to
|
|
299
|
+
install a checkout, run the two test suites and send a change.
|
|
300
|
+
|
|
301
|
+
## Licence
|
|
302
|
+
|
|
303
|
+
MIT. See [LICENSE](https://github.com/poisson-labs/prove/blob/main/LICENSE) and
|
|
304
|
+
[NOTICE](https://github.com/poisson-labs/prove/blob/main/NOTICE) for what Prove includes from others.
|
|
305
|
+
|
|
306
|
+
## Citation
|
|
307
|
+
|
|
308
|
+
<!-- docs-check: skip: a citation to copy, not a command -->
|
|
309
|
+
```bibtex
|
|
310
|
+
@software{poisson_prove,
|
|
311
|
+
title = {Poisson Prove},
|
|
312
|
+
author = {{Poisson Labs}},
|
|
313
|
+
year = {2026},
|
|
314
|
+
url = {https://github.com/poisson-labs/prove}
|
|
315
|
+
}
|
|
316
|
+
```
|