deterministic-scenario-engine 2.1.1__tar.gz → 2.1.2__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.
- {deterministic_scenario_engine-2.1.1/src/deterministic_scenario_engine.egg-info → deterministic_scenario_engine-2.1.2}/PKG-INFO +4 -3
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/README.md +2 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/phase2-architecture.md +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/pyproject.toml +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2/src/deterministic_scenario_engine.egg-info}/PKG-INFO +4 -3
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/deterministic_scenario_engine.egg-info/SOURCES.txt +2 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/deterministic_scenario_engine.egg-info/requires.txt +1 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/_version.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_2b_json_pytest_integration.py +9 -15
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_4_control_flow.py +5 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_6_sqlalchemy_materializer.py +5 -3
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_7_plugins_ecommerce.py +5 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_8_hypothesis_schemathesis.py +2 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_1_0c_dsl_compatibility_contract.py +2 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_1_0e_packaging_release_candidate.py +2 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_10_workflow_demonstrators.py +2 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_12_public_contract_docs_freeze.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_13_packaging_fresh_install_rc.py +2 -2
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_1_v1_read_contract.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_2_composition.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_3_matrix.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_4_batch.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_5_inspect_explain.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_7_cli_product_surface.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_11_public_contract_docs_freeze.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_1_evidence_bundle_contract.py +1 -1
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_readme_pypi_portability.py +24 -0
- deterministic_scenario_engine-2.1.2/tests/test_test_portability.py +26 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/LICENSE +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/MANIFEST.in +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/api.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/compatibility.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/determinism.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/dsl-reference.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/hypothesis.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/phase2-public-contract.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/phase3-architecture.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/phase3-public-contract.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/plugins.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/product-evidence-gate.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/quickstart.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/release-process.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/reproducibility.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/schemathesis.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/security-and-non-goals.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/sqlalchemy.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/testing-oracle.md +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/api_scenario.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/cart.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/control_flow.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/ecommerce.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/openapi.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/oracle_fault.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_1b_cart.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_3_resources.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_4_control_flow.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_5_oracle_fault.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_6_sqlalchemy_rows.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_7_ecommerce_plugin.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_8_api_scenario.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase0_8_openapi.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/phase3_ecommerce_evidence.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/resources.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/sqlalchemy_rows.yaml +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/setup.cfg +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/deterministic_scenario_engine.egg-info/dependency_links.txt +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/deterministic_scenario_engine.egg-info/entry_points.txt +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/deterministic_scenario_engine.egg-info/top_level.txt +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/adapters/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/adapters/json_file.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/adapters/sqlalchemy.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/address.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/artifacts.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/batch/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/batch/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/batch/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/batch/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/batch/runtime.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/cli/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/cli/__main__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/cli/main.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/clock.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/parser.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/resolver.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/composition/runtime.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/context.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/control_flow.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/compare.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/render.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/diff/serialization.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/domain_packs/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/domain_packs/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/domain_packs/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/domain_packs/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/domain_packs/registry.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/compiler.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/parser.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/dsl/runtime.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/adapter.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/compatibility.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/export.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/fixture.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/migration.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/evidence/read.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/expressions.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/faults.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/history.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/ids.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/explain.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/inspect.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/redaction.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/inspection/serialization.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/integrations/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/integrations/hypothesis.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/integrations/schemathesis.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/invariants.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/manifest.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/canonical.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/expand.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/filtering.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/matrix/runtime.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle_assertions/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle_assertions/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle_assertions/evaluate.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle_assertions/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/oracle_assertions/serialization.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/plugins.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/provenance.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/pytest_plugin.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/reference_packs/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/reference_packs/ecommerce.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/reference_packs/ecommerce_evidence.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/resources.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/result.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/rng.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/runner.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/state.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/suite/__init__.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/suite/errors.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/suite/models.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/suite/read.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/suite/serialization.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/validation.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/src/scenario_engine/values.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_1a_semantic_kernel.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_1b_linear_dsl.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_1c_integrated_phase0_1.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_1c_r1_missing_sentinel_repair.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_2a_reproducible_results.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_3_resources_constraints.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_0_5_oracle_faults.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_1_0b_public_api_error_contract.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_1_0d_documentation_examples.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_11_performance_scale_hardening.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_1_models_serialization.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_6_structured_semantic_diff.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_8_domain_pack_foundation.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_2_9_oracle_assertions.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_10_performance_security_hardening.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_12_packaging_fresh_install_rc.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_2_safe_bundle_reader_validator.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_3_ordered_export.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_4_evidence_adapter_contract.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_5_compatibility_migration_planner.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_6_lossless_migrations_fixture_export.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_7_cli_interchange_surface.py +0 -0
- {deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/tests/test_phase_3_8_ecommerce_evidence_workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deterministic-scenario-engine
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Reproducible, state-consistent business scenarios with deterministic ground truth
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/imshahinul/deterministic-scenario-engine
|
|
@@ -25,6 +25,7 @@ License-File: LICENSE
|
|
|
25
25
|
Requires-Dist: PyYAML==6.0.3
|
|
26
26
|
Provides-Extra: pytest
|
|
27
27
|
Requires-Dist: pytest<10,>=9.1; extra == "pytest"
|
|
28
|
+
Requires-Dist: build<2,>=1; extra == "pytest"
|
|
28
29
|
Provides-Extra: sqlalchemy
|
|
29
30
|
Requires-Dist: SQLAlchemy<3,>=2.0; extra == "sqlalchemy"
|
|
30
31
|
Provides-Extra: hypothesis
|
|
@@ -40,7 +41,7 @@ Dynamic: license-file
|
|
|
40
41
|
|
|
41
42
|
Deterministic Scenario Engine (DSE) creates reproducible, state-consistent
|
|
42
43
|
business histories and deterministic scenario suites with ground truth for
|
|
43
|
-
testing. The source-tree distribution version is 2.1.
|
|
44
|
+
testing. The source-tree distribution version is 2.1.2. Distribution release
|
|
44
45
|
identity and deterministic compatibility identity are separate:
|
|
45
46
|
`ENGINE_VERSION` remains 1.0.0 and DSL version remains 1. For authoritative
|
|
46
47
|
public-release availability and history, see PyPI and GitHub Releases.
|
|
@@ -167,7 +168,7 @@ Unsupported cross-version replay fails explicitly. See the [determinism model](h
|
|
|
167
168
|
## Status
|
|
168
169
|
|
|
169
170
|
Distribution release identity and deterministic engine compatibility are
|
|
170
|
-
separate contracts. This source tree reports distribution version 2.1.
|
|
171
|
+
separate contracts. This source tree reports distribution version 2.1.2;
|
|
171
172
|
generated core manifests retain `ENGINE_VERSION` 1.0.0 and DSL 1. PyPI and
|
|
172
173
|
GitHub Releases are the authoritative sources for public-release availability
|
|
173
174
|
and history. The project is licensed under Apache-2.0.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Deterministic Scenario Engine (DSE) creates reproducible, state-consistent
|
|
6
6
|
business histories and deterministic scenario suites with ground truth for
|
|
7
|
-
testing. The source-tree distribution version is 2.1.
|
|
7
|
+
testing. The source-tree distribution version is 2.1.2. Distribution release
|
|
8
8
|
identity and deterministic compatibility identity are separate:
|
|
9
9
|
`ENGINE_VERSION` remains 1.0.0 and DSL version remains 1. For authoritative
|
|
10
10
|
public-release availability and history, see PyPI and GitHub Releases.
|
|
@@ -131,7 +131,7 @@ Unsupported cross-version replay fails explicitly. See the [determinism model](h
|
|
|
131
131
|
## Status
|
|
132
132
|
|
|
133
133
|
Distribution release identity and deterministic engine compatibility are
|
|
134
|
-
separate contracts. This source tree reports distribution version 2.1.
|
|
134
|
+
separate contracts. This source tree reports distribution version 2.1.2;
|
|
135
135
|
generated core manifests retain `ENGINE_VERSION` 1.0.0 and DSL 1. PyPI and
|
|
136
136
|
GitHub Releases are the authoritative sources for public-release availability
|
|
137
137
|
and history. The project is licensed under Apache-2.0.
|
|
@@ -275,7 +275,7 @@ From the 2026-09-03 freeze, the likely range is roughly late October through lat
|
|
|
275
275
|
|
|
276
276
|
## V1 Contract Validation
|
|
277
277
|
|
|
278
|
-
Pre-mutation validation ran from repository
|
|
278
|
+
Pre-mutation validation ran from `<repository-root>` on branch `main`. HEAD/main/origin-main were `ee29f52f714e84f17e1048ce24192fcf1c69345a`, tree `2a61915d578dcb1c4ec94049350a24d2cabdf721`, divergence `0/0`, with zero staged, unstaged, or untracked paths. The sole remote was `origin`, resolving to public `imshahinul/deterministic-scenario-engine`; tag `1.0.0` peeled to the baseline and its tree.
|
|
279
279
|
|
|
280
280
|
Validation used CPython 3.14.6 in isolated environment `/tmp/dse-phase2-0a-venv`, pytest 9.1.1, PyYAML 6.0.3, SQLAlchemy 2.0.52, Hypothesis 6.167.1, and Schemathesis 4.25.2, with repository `src` on `PYTHONPATH`. Canonical validation is `python -m pytest -q`; collection is `python -m pytest --collect-only -q`. It collected 280 tests and the full run passed: `280 passed, 136 subtests passed` in 41.94 seconds. Focused golden enforcement passed 4 tests and 3 subtests.
|
|
281
281
|
|
|
@@ -36,7 +36,7 @@ Issues = "https://github.com/imshahinul/deterministic-scenario-engine/issues"
|
|
|
36
36
|
scenario = "scenario_engine.cli:main"
|
|
37
37
|
|
|
38
38
|
[project.optional-dependencies]
|
|
39
|
-
pytest = ["pytest>=9.1,<10"]
|
|
39
|
+
pytest = ["pytest>=9.1,<10", "build>=1,<2"]
|
|
40
40
|
sqlalchemy = ["SQLAlchemy>=2.0,<3"]
|
|
41
41
|
hypothesis = ["hypothesis>=6,<7"]
|
|
42
42
|
schemathesis = ["hypothesis>=6,<7", "schemathesis>=4,<5"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deterministic-scenario-engine
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Reproducible, state-consistent business scenarios with deterministic ground truth
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/imshahinul/deterministic-scenario-engine
|
|
@@ -25,6 +25,7 @@ License-File: LICENSE
|
|
|
25
25
|
Requires-Dist: PyYAML==6.0.3
|
|
26
26
|
Provides-Extra: pytest
|
|
27
27
|
Requires-Dist: pytest<10,>=9.1; extra == "pytest"
|
|
28
|
+
Requires-Dist: build<2,>=1; extra == "pytest"
|
|
28
29
|
Provides-Extra: sqlalchemy
|
|
29
30
|
Requires-Dist: SQLAlchemy<3,>=2.0; extra == "sqlalchemy"
|
|
30
31
|
Provides-Extra: hypothesis
|
|
@@ -40,7 +41,7 @@ Dynamic: license-file
|
|
|
40
41
|
|
|
41
42
|
Deterministic Scenario Engine (DSE) creates reproducible, state-consistent
|
|
42
43
|
business histories and deterministic scenario suites with ground truth for
|
|
43
|
-
testing. The source-tree distribution version is 2.1.
|
|
44
|
+
testing. The source-tree distribution version is 2.1.2. Distribution release
|
|
44
45
|
identity and deterministic compatibility identity are separate:
|
|
45
46
|
`ENGINE_VERSION` remains 1.0.0 and DSL version remains 1. For authoritative
|
|
46
47
|
public-release availability and history, see PyPI and GitHub Releases.
|
|
@@ -167,7 +168,7 @@ Unsupported cross-version replay fails explicitly. See the [determinism model](h
|
|
|
167
168
|
## Status
|
|
168
169
|
|
|
169
170
|
Distribution release identity and deterministic engine compatibility are
|
|
170
|
-
separate contracts. This source tree reports distribution version 2.1.
|
|
171
|
+
separate contracts. This source tree reports distribution version 2.1.2;
|
|
171
172
|
generated core manifests retain `ENGINE_VERSION` 1.0.0 and DSL 1. PyPI and
|
|
172
173
|
GitHub Releases are the authoritative sources for public-release availability
|
|
173
174
|
and history. The project is licensed under Apache-2.0.
|
|
@@ -185,4 +185,5 @@ tests/test_phase_3_5_compatibility_migration_planner.py
|
|
|
185
185
|
tests/test_phase_3_6_lossless_migrations_fixture_export.py
|
|
186
186
|
tests/test_phase_3_7_cli_interchange_surface.py
|
|
187
187
|
tests/test_phase_3_8_ecommerce_evidence_workflow.py
|
|
188
|
-
tests/test_readme_pypi_portability.py
|
|
188
|
+
tests/test_readme_pypi_portability.py
|
|
189
|
+
tests/test_test_portability.py
|
|
@@ -17,9 +17,6 @@ from scenario_engine.result import ScenarioResult
|
|
|
17
17
|
|
|
18
18
|
ROOT = Path(__file__).parents[1]
|
|
19
19
|
SRC = ROOT / "src"
|
|
20
|
-
AUDIT_PYTHON = Path(
|
|
21
|
-
"/Users/smshahinulislam/Developer/scenario-engine-audit/runtime-venv/bin/python"
|
|
22
|
-
)
|
|
23
20
|
SCENARIO = """
|
|
24
21
|
dsl_version: 1
|
|
25
22
|
scenario: phase02b
|
|
@@ -47,11 +44,12 @@ def run_result(seed: str = "seed", run_index: int = 0) -> ScenarioResult:
|
|
|
47
44
|
)
|
|
48
45
|
|
|
49
46
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
def pytest_command(test_file: Path) -> list[str]:
|
|
48
|
+
command = [sys.executable, "-m", "pytest", "-q"]
|
|
49
|
+
if os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"):
|
|
50
|
+
command.extend(("-p", "scenario_engine"))
|
|
51
|
+
command.append(str(test_file))
|
|
52
|
+
return command
|
|
55
53
|
|
|
56
54
|
|
|
57
55
|
class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
@@ -161,7 +159,7 @@ class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
|
161
159
|
document = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
162
160
|
self.assertEqual(document["project"]["dependencies"], ["PyYAML==6.0.3"])
|
|
163
161
|
self.assertEqual(document["project"]["optional-dependencies"]["pytest"],
|
|
164
|
-
["pytest>=9.1,<10"])
|
|
162
|
+
["pytest>=9.1,<10", "build>=1,<2"])
|
|
165
163
|
self.assertEqual(document["project"]["entry-points"]["pytest11"]["scenario_engine"],
|
|
166
164
|
"scenario_engine.pytest_plugin")
|
|
167
165
|
|
|
@@ -169,7 +167,6 @@ class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
|
169
167
|
with tempfile.TemporaryDirectory() as directory:
|
|
170
168
|
test_file = Path(directory) / "test_fixture.py"
|
|
171
169
|
test_file.write_text(textwrap.dedent(f'''\
|
|
172
|
-
pytest_plugins = ["scenario_engine.pytest_plugin"]
|
|
173
170
|
from scenario_engine.result import ScenarioResult
|
|
174
171
|
SCENARIO = {SCENARIO!r}
|
|
175
172
|
def test_fixture(scenario_engine):
|
|
@@ -180,8 +177,7 @@ class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
|
180
177
|
assert first.manifest.run_index == 4
|
|
181
178
|
'''), encoding="utf-8")
|
|
182
179
|
completed = subprocess.run(
|
|
183
|
-
|
|
184
|
-
cwd=directory, env=subprocess_environment(), capture_output=True, text=True,
|
|
180
|
+
pytest_command(test_file), cwd=directory, capture_output=True, text=True,
|
|
185
181
|
)
|
|
186
182
|
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr)
|
|
187
183
|
|
|
@@ -191,7 +187,6 @@ class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
|
191
187
|
source.write_text(SCENARIO, encoding="utf-8")
|
|
192
188
|
test_file = Path(directory) / "test_file_fixture.py"
|
|
193
189
|
test_file.write_text(textwrap.dedent(f'''\
|
|
194
|
-
pytest_plugins = ["scenario_engine.pytest_plugin"]
|
|
195
190
|
from pathlib import Path
|
|
196
191
|
from scenario_engine.result import ScenarioResult
|
|
197
192
|
def test_file_fixture(scenario_engine):
|
|
@@ -201,8 +196,7 @@ class Phase02BJsonPytestIntegrationTests(unittest.TestCase):
|
|
|
201
196
|
assert result.final_state["money"].as_tuple().exponent == -2
|
|
202
197
|
'''), encoding="utf-8")
|
|
203
198
|
completed = subprocess.run(
|
|
204
|
-
|
|
205
|
-
cwd=directory, env=subprocess_environment(), capture_output=True, text=True,
|
|
199
|
+
pytest_command(test_file), cwd=directory, capture_output=True, text=True,
|
|
206
200
|
)
|
|
207
201
|
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr)
|
|
208
202
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import subprocess
|
|
4
5
|
import sys
|
|
5
6
|
import tempfile
|
|
@@ -168,8 +169,10 @@ class Phase04ControlFlowTests(unittest.TestCase):
|
|
|
168
169
|
|
|
169
170
|
def test_pytest_harness_runs_branch_subflow_repeat_scenario(self):
|
|
170
171
|
with tempfile.TemporaryDirectory() as directory:
|
|
171
|
-
path = Path(directory) / "test_real.py"; path.write_text('''from pathlib import Path\
|
|
172
|
-
|
|
172
|
+
path = Path(directory) / "test_real.py"; path.write_text('''from pathlib import Path\ndef test_flow(scenario_engine):\n t=Path("examples/phase0_4_control_flow.yaml").read_text(); i={"premium":True,"retry_count":2,"customer_id":"c"}; r=scenario_engine.run_text(t,root_seed="s",inputs=i); assert r.to_json()==scenario_engine.replay_text(t,r.manifest,inputs=i).to_json()\n''')
|
|
173
|
+
command = [sys.executable, "-m", "pytest", "-q"]
|
|
174
|
+
if os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"): command.extend(("-p", "scenario_engine"))
|
|
175
|
+
completed = subprocess.run([*command, str(path)], capture_output=True, text=True)
|
|
173
176
|
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr)
|
|
174
177
|
|
|
175
178
|
def test_phase0_4_example_and_all_prior_examples_remain_compatible(self):
|
|
@@ -4,6 +4,7 @@ import ast
|
|
|
4
4
|
from datetime import datetime, timedelta, timezone
|
|
5
5
|
from decimal import Decimal
|
|
6
6
|
import importlib.util
|
|
7
|
+
import os
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
import subprocess
|
|
9
10
|
import sys
|
|
@@ -83,7 +84,7 @@ class Phase06SqlAlchemyMaterializerTests(unittest.TestCase):
|
|
|
83
84
|
def test_sqlalchemy_extra_is_optional_and_core_dependency_contract_unchanged(self):
|
|
84
85
|
doc = tomllib.loads((ROOT / "pyproject.toml").read_text())
|
|
85
86
|
self.assertEqual(doc["project"]["dependencies"], ["PyYAML==6.0.3"])
|
|
86
|
-
self.assertEqual(doc["project"]["optional-dependencies"]["pytest"], ["pytest>=9.1,<10"])
|
|
87
|
+
self.assertEqual(doc["project"]["optional-dependencies"]["pytest"], ["pytest>=9.1,<10", "build>=1,<2"])
|
|
87
88
|
self.assertEqual(doc["project"]["optional-dependencies"]["sqlalchemy"], ["SQLAlchemy>=2.0,<3"])
|
|
88
89
|
|
|
89
90
|
def test_core_import_does_not_require_or_eagerly_import_sqlalchemy(self):
|
|
@@ -194,13 +195,14 @@ class Phase06SqlAlchemyMaterializerTests(unittest.TestCase):
|
|
|
194
195
|
from pathlib import Path
|
|
195
196
|
from sqlalchemy import *
|
|
196
197
|
from scenario_engine.adapters.sqlalchemy import *
|
|
197
|
-
pytest_plugins=["scenario_engine.pytest_plugin"]
|
|
198
198
|
def test_real(scenario_engine):
|
|
199
199
|
text=Path({str(EXAMPLE)!r}).read_text(); result=scenario_engine.run_text(text,root_seed="p")
|
|
200
200
|
engine=create_engine("sqlite:///:memory:"); metadata=MetaData(); customers=Table("customers",metadata,Column("id",String,primary_key=True),Column("name",String)); orders=Table("orders",metadata,Column("id",String,primary_key=True),Column("customer_id",String),Column("amount",Integer)); metadata.create_all(engine)
|
|
201
201
|
report=materialize_result(engine,result,{{"customers":customers,"orders":orders}}); replay=scenario_engine.replay_text(text,result.manifest); assert report.rows_inserted==2; assert command_fingerprint(extract_row_commands(result))==command_fingerprint(extract_row_commands(replay))
|
|
202
202
|
'''))
|
|
203
|
-
|
|
203
|
+
command = [sys.executable, "-m", "pytest", "-q"]
|
|
204
|
+
if os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"): command.extend(("-p", "scenario_engine"))
|
|
205
|
+
completed = subprocess.run([*command, str(path)], cwd=ROOT, capture_output=True, text=True)
|
|
204
206
|
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr)
|
|
205
207
|
|
|
206
208
|
def test_phase0_6_example_and_all_prior_examples_remain_compatible(self):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
|
+
import os
|
|
4
5
|
from datetime import datetime, timezone
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
import subprocess
|
|
@@ -189,8 +190,10 @@ class PluginEcommerceTests(unittest.TestCase):
|
|
|
189
190
|
|
|
190
191
|
def test_real_pytest_harness_accepts_explicit_plugin_registry(self):
|
|
191
192
|
with tempfile.TemporaryDirectory() as directory:
|
|
192
|
-
path=Path(directory)/"test_plugin.py"; path.write_text('
|
|
193
|
-
|
|
193
|
+
path=Path(directory)/"test_plugin.py"; path.write_text('from pathlib import Path\nfrom scenario_engine.reference_packs.ecommerce import ecommerce_registry\ndef test_it(scenario_engine):\n t=Path("examples/phase0_7_ecommerce_plugin.yaml").read_text(); i={"email_domain":"example.test"}; r=scenario_engine.run_text(t,root_seed="s",inputs=i,plugins=ecommerce_registry()); assert r.to_json_bytes()==scenario_engine.replay_text(t,r.manifest,inputs=i,plugins=ecommerce_registry()).to_json_bytes()\n')
|
|
194
|
+
command=[sys.executable,"-m","pytest","-q"]
|
|
195
|
+
if os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"): command.extend(("-p","scenario_engine"))
|
|
196
|
+
completed=subprocess.run([*command,str(path)],capture_output=True,text=True)
|
|
194
197
|
self.assertEqual(0,completed.returncode,completed.stdout+completed.stderr)
|
|
195
198
|
|
|
196
199
|
def test_phase0_7_example_and_all_prior_examples_remain_compatible(self):
|
|
@@ -55,7 +55,7 @@ class Phase08HypothesisSchemathesisTests(unittest.TestCase):
|
|
|
55
55
|
project = tomllib.loads((ROOT / "pyproject.toml").read_text())["project"]
|
|
56
56
|
self.assertEqual(project["dependencies"], ["PyYAML==6.0.3"])
|
|
57
57
|
extras = project["optional-dependencies"]
|
|
58
|
-
self.assertEqual(extras["pytest"], ["pytest>=9.1,<10"]); self.assertEqual(extras["sqlalchemy"], ["SQLAlchemy>=2.0,<3"])
|
|
58
|
+
self.assertEqual(extras["pytest"], ["pytest>=9.1,<10", "build>=1,<2"]); self.assertEqual(extras["sqlalchemy"], ["SQLAlchemy>=2.0,<3"])
|
|
59
59
|
self.assertEqual(extras["hypothesis"], ["hypothesis>=6,<7"]); self.assertEqual(set(extras["schemathesis"]), {"hypothesis>=6,<7", "schemathesis>=4,<5"})
|
|
60
60
|
|
|
61
61
|
def test_core_and_integrations_package_import_without_hypothesis_or_schemathesis(self):
|
|
@@ -144,7 +144,7 @@ class Phase08HypothesisSchemathesisTests(unittest.TestCase):
|
|
|
144
144
|
self.assertEqual(before, (outside.manifest, outside.normalized(), outside.to_json_bytes()))
|
|
145
145
|
|
|
146
146
|
def test_real_pytest_runs_hypothesis_and_local_schemathesis_composition(self):
|
|
147
|
-
with tempfile.TemporaryDirectory(
|
|
147
|
+
with tempfile.TemporaryDirectory() as directory:
|
|
148
148
|
path = Path(directory) / "test_phase08_real.py"
|
|
149
149
|
path.write_text("""from pathlib import Path\nimport yaml,schemathesis\nfrom hypothesis import given,settings,strategies as st\nfrom scenario_engine.integrations.hypothesis import scenario_cases\nfrom scenario_engine.integrations.schemathesis import SchemathesisCaseBindings,operation_cases\nfrom scenario_engine.reference_packs.ecommerce import ecommerce_registry\nfrom scenario_engine.dsl.runtime import replay_scenario\nROOT=Path(r'""" + str(ROOT) + """')\ny=(ROOT/'examples/phase0_8_api_scenario.yaml').read_text(); spec=yaml.safe_load((ROOT/'examples/phase0_8_openapi.yaml').read_text()); op=schemathesis.openapi.from_dict(spec)['/orders']['POST']\nss=scenario_cases(y,root_seed='real',run_indexes=st.integers(0,2),inputs=st.fixed_dictionaries({'customer_id':st.just('c'),'email_domain':st.just('example.test'),'quantity':st.integers(1,5)}),plugins=ecommerce_registry())\nb=SchemathesisCaseBindings(body={'quantity':'state.quantity','order_number':'state.order_number'})\n@given(operation_cases(op,ss,b))\n@settings(max_examples=5,database=None,deadline=None)\ndef test_real(x):\n assert x.case.body['quantity']==x.scenario.inputs['quantity']; assert x.scenario.result.to_json_bytes()==replay_scenario(x.scenario.yaml_text,x.scenario.result.manifest,inputs=dict(x.scenario.inputs),plugins=ecommerce_registry()).to_json_bytes()\n""")
|
|
150
150
|
completed = subprocess.run([sys.executable, "-m", "pytest", "-q", str(path)], cwd=ROOT, capture_output=True, text=True)
|
|
@@ -26,11 +26,12 @@ ENV = EvaluationEnvironment({}, {}, {})
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def document(initial: str = "{}", steps: str | None = None, extra: str = "") -> str:
|
|
29
|
+
rendered_steps = steps or " - {id: done, transition: null}\n"
|
|
29
30
|
return (
|
|
30
31
|
"dsl_version: 1\nscenario: contract\n"
|
|
31
32
|
"clock: {start: '2026-01-01T00:00:00Z'}\n"
|
|
32
33
|
f"initial_state: {initial}\n"
|
|
33
|
-
f"steps:\n{
|
|
34
|
+
f"steps:\n{rendered_steps}"
|
|
34
35
|
f"{extra}"
|
|
35
36
|
)
|
|
36
37
|
|
|
@@ -54,7 +54,7 @@ class Phase10EPackagingReleaseCandidateTests(unittest.TestCase):
|
|
|
54
54
|
"scenario_engine._version.VERSION",
|
|
55
55
|
)
|
|
56
56
|
# Phase 2 changes package identity, not the frozen deterministic contract.
|
|
57
|
-
self.assertEqual(VERSION, "2.1.
|
|
57
|
+
self.assertEqual(VERSION, "2.1.2")
|
|
58
58
|
self.assertEqual(ENGINE_VERSION, "1.0.0")
|
|
59
59
|
|
|
60
60
|
def test_license_readme_and_build_backend_metadata(self):
|
|
@@ -84,7 +84,7 @@ class Phase10EPackagingReleaseCandidateTests(unittest.TestCase):
|
|
|
84
84
|
self.assertEqual(self.project["requires-python"], ">=3.11")
|
|
85
85
|
self.assertEqual(self.project["dependencies"], ["PyYAML==6.0.3"])
|
|
86
86
|
self.assertEqual(self.project["optional-dependencies"], {
|
|
87
|
-
"pytest": ["pytest>=9.1,<10"],
|
|
87
|
+
"pytest": ["pytest>=9.1,<10", "build>=1,<2"],
|
|
88
88
|
"sqlalchemy": ["SQLAlchemy>=2.0,<3"],
|
|
89
89
|
"hypothesis": ["hypothesis>=6,<7"],
|
|
90
90
|
"schemathesis": ["hypothesis>=6,<7", "schemathesis>=4,<5"],
|
|
@@ -148,7 +148,7 @@ def test_fresh_tree_wheel_supports_workflow_public_commands(tmp_path: Path) -> N
|
|
|
148
148
|
check=True,
|
|
149
149
|
)
|
|
150
150
|
wheels = list(wheelhouse.glob(f"deterministic_scenario_engine-{VERSION}-*.whl"))
|
|
151
|
-
assert VERSION == "2.1.
|
|
151
|
+
assert VERSION == "2.1.2"
|
|
152
152
|
assert len(wheels) == 1
|
|
153
153
|
wheel = wheels[0]
|
|
154
154
|
installed = tmp_path / "installed"
|
|
@@ -175,7 +175,7 @@ def test_fresh_tree_wheel_supports_workflow_public_commands(tmp_path: Path) -> N
|
|
|
175
175
|
text=True,
|
|
176
176
|
)
|
|
177
177
|
distribution_version, import_path = identity.stdout.splitlines()
|
|
178
|
-
assert distribution_version == VERSION == "2.1.
|
|
178
|
+
assert distribution_version == VERSION == "2.1.2"
|
|
179
179
|
assert Path(import_path).is_relative_to(installed)
|
|
180
180
|
validate = subprocess.run(
|
|
181
181
|
[sys.executable, "-m", "scenario_engine.cli", "--json", "validate", "examples/cart.yaml"],
|
|
@@ -62,7 +62,7 @@ def test_versions_errors_commands_and_entry_points_are_frozen() -> None:
|
|
|
62
62
|
from scenario_engine.oracle_assertions import ORACLE_ASSERTION_SCHEMA_VERSION
|
|
63
63
|
from scenario_engine.suite import READ_SCHEMA_VERSION, SUITE_SCHEMA_VERSION
|
|
64
64
|
|
|
65
|
-
assert VERSION == "2.1.
|
|
65
|
+
assert VERSION == "2.1.2"
|
|
66
66
|
assert (COMPOSITION_CONTRACT_VERSION, MATRIX_PLAN_CONTRACT_VERSION) == (
|
|
67
67
|
"composition.modules/1", "matrix.plan/1")
|
|
68
68
|
assert (READ_SCHEMA_VERSION, SUITE_SCHEMA_VERSION) == (
|
|
@@ -58,7 +58,7 @@ def _cases():
|
|
|
58
58
|
def test_version_roles_are_explicit_and_dsl_remains_one() -> None:
|
|
59
59
|
config = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
60
60
|
assert config["tool"]["setuptools"]["dynamic"]["version"]["attr"] == "scenario_engine._version.VERSION"
|
|
61
|
-
assert VERSION == "2.1.
|
|
61
|
+
assert VERSION == "2.1.2"
|
|
62
62
|
assert ENGINE_VERSION == scenario_engine.ENGINE_VERSION == "1.0.0"
|
|
63
63
|
_, result = _result("cart.yaml", "s")
|
|
64
64
|
assert result.manifest.engine_version == "1.0.0"
|
|
@@ -120,4 +120,4 @@ def test_entry_points_and_release_candidate_wording_are_preserved() -> None:
|
|
|
120
120
|
# transient publication state while historical contracts remain immutable.
|
|
121
121
|
assert "unpublished 2.0.0 release candidate" not in docs
|
|
122
122
|
assert "no pypi or github release has occurred yet" not in docs
|
|
123
|
-
assert "2.1.
|
|
123
|
+
assert "2.1.2" in docs
|
|
@@ -105,7 +105,7 @@ class V1ReadTests(unittest.TestCase):
|
|
|
105
105
|
|
|
106
106
|
def test_v1_api_version_and_three_result_goldens_remain_unchanged(self):
|
|
107
107
|
expected = scenario_engine.__all__
|
|
108
|
-
self.assertEqual(VERSION, "2.1.
|
|
108
|
+
self.assertEqual(VERSION, "2.1.2")
|
|
109
109
|
self.assertEqual(scenario_engine.__all__, expected)
|
|
110
110
|
cart_source = (ROOT / "examples" / "phase0_1b_cart.yaml").read_text()
|
|
111
111
|
cart = run_scenario(compile_document(parse_yaml(cart_source)), "s")
|
|
@@ -376,7 +376,7 @@ def test_suite_manifest_identity_order_child_reference_and_v1_preservation(tmp_p
|
|
|
376
376
|
|
|
377
377
|
def test_top_level_api_and_v1_parser_are_unchanged(tmp_path: Path) -> None:
|
|
378
378
|
assert "load_composed_suite" not in scenario_engine.__all__
|
|
379
|
-
assert VERSION == "2.1.
|
|
379
|
+
assert VERSION == "2.1.2"
|
|
380
380
|
root_without_composition = _root(" alpha: alpha.yaml").replace(
|
|
381
381
|
"composition:\n modules:\n alpha: alpha.yaml\n", "",
|
|
382
382
|
)
|
|
@@ -235,7 +235,7 @@ steps:
|
|
|
235
235
|
|
|
236
236
|
def test_top_level_api_and_package_version_are_unchanged() -> None:
|
|
237
237
|
assert "MatrixPlan" not in scenario_engine.__all__
|
|
238
|
-
assert VERSION == "2.1.
|
|
238
|
+
assert VERSION == "2.1.2"
|
|
239
239
|
|
|
240
240
|
|
|
241
241
|
def test_static_matrix_package_has_no_nondeterministic_or_unsafe_imports() -> None:
|
|
@@ -277,7 +277,7 @@ def test_public_boundary_version_preservation_and_static_safety() -> None:
|
|
|
277
277
|
from scenario_engine._version import VERSION
|
|
278
278
|
|
|
279
279
|
assert "BatchPlan" not in scenario_engine.__all__
|
|
280
|
-
assert VERSION == "2.1.
|
|
280
|
+
assert VERSION == "2.1.2"
|
|
281
281
|
forbidden = {"random", "secrets", "socket", "subprocess", "importlib", "os", "time", "urllib"}
|
|
282
282
|
root = Path(__file__).parents[1] / "src/scenario_engine/batch"
|
|
283
283
|
for path in root.glob("*.py"):
|
|
@@ -151,4 +151,4 @@ def test_bounds_are_exact_and_fail_deterministically(monkeypatch) -> None:
|
|
|
151
151
|
|
|
152
152
|
def test_root_api_and_package_version_remain_frozen() -> None:
|
|
153
153
|
assert "inspect_result" not in scenario_engine.__all__
|
|
154
|
-
assert VERSION == "2.1.
|
|
154
|
+
assert VERSION == "2.1.2"
|
|
@@ -246,4 +246,4 @@ def test_cli_static_purity_version_and_console_script_contract() -> None:
|
|
|
246
246
|
assert imported.isdisjoint(forbidden)
|
|
247
247
|
pyproject = (ROOT / "pyproject.toml").read_text(encoding="utf-8")
|
|
248
248
|
assert 'scenario = "scenario_engine.cli:main"' in pyproject
|
|
249
|
-
assert 'VERSION = "2.1.
|
|
249
|
+
assert 'VERSION = "2.1.2"' in (ROOT / "src/scenario_engine/_version.py").read_text(encoding="utf-8")
|
|
@@ -162,7 +162,7 @@ def test_versions_publication_security_reference_and_links_are_frozen(tmp_path:
|
|
|
162
162
|
from scenario_engine.reference_packs import ecommerce_domain_pack, export_ecommerce_evidence
|
|
163
163
|
|
|
164
164
|
result = run_scenario(compile_document(parse_yaml((ROOT / "examples/cart.yaml").read_text())), "phase3.11")
|
|
165
|
-
assert VERSION == "2.1.
|
|
165
|
+
assert VERSION == "2.1.2" and ENGINE_VERSION == "1.0.0"
|
|
166
166
|
assert result.manifest.engine_version == "1.0.0" and result.manifest.dsl_version == 1
|
|
167
167
|
contract = CONTRACT.read_text()
|
|
168
168
|
assert "current source distribution version=2.1.0" in contract
|
|
@@ -253,7 +253,7 @@ def test_phase2_root_api_and_version_roles_remain_frozen() -> None:
|
|
|
253
253
|
from scenario_engine.suite import RUN_SCHEMA_VERSION, SUITE_SCHEMA_VERSION
|
|
254
254
|
|
|
255
255
|
assert tuple(scenario_engine.__all__) == FROZEN_ROOT_EXPORTS
|
|
256
|
-
assert VERSION == "2.1.
|
|
256
|
+
assert VERSION == "2.1.2"
|
|
257
257
|
assert ENGINE_VERSION == "1.0.0"
|
|
258
258
|
assert RUN_SCHEMA_VERSION == "suite.run/1"
|
|
259
259
|
assert SUITE_SCHEMA_VERSION == "suite.manifest/1"
|
|
@@ -16,6 +16,22 @@ import zipfile
|
|
|
16
16
|
ROOT = Path(__file__).parents[1]
|
|
17
17
|
MARKDOWN_TARGET = re.compile(r"!?\[[^]]*\]\((?:<)?([^)>\s]+)(?:>)?(?:\s+[^)]*)?\)")
|
|
18
18
|
ALLOWED_SCHEMES = {"http", "https", "mailto"}
|
|
19
|
+
MAINTAINER_LOCAL_PATH = re.compile(
|
|
20
|
+
r"/Users/" + "smshahinulislam"
|
|
21
|
+
+ r"|/Users/[^/\s]+/Developer/scenario-engine|Developer/"
|
|
22
|
+
+ r"scenario-engine-audit|scenario-engine-audit/"
|
|
23
|
+
+ r"runtime-venv"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def packaged_documentation() -> list[Path]:
|
|
28
|
+
return [
|
|
29
|
+
ROOT / "README.md",
|
|
30
|
+
ROOT / "pyproject.toml",
|
|
31
|
+
ROOT / "MANIFEST.in",
|
|
32
|
+
*(ROOT / "docs").glob("*.md"),
|
|
33
|
+
*(path for path in (ROOT / "examples").iterdir() if path.is_file()),
|
|
34
|
+
]
|
|
19
35
|
|
|
20
36
|
|
|
21
37
|
def assert_portable(test: unittest.TestCase, description: str) -> None:
|
|
@@ -33,6 +49,14 @@ def metadata_description(payload: bytes) -> str:
|
|
|
33
49
|
|
|
34
50
|
|
|
35
51
|
class ReadmePyPIPortabilityTests(unittest.TestCase):
|
|
52
|
+
def test_packaged_documentation_has_no_maintainer_local_paths(self):
|
|
53
|
+
occurrences = []
|
|
54
|
+
for path in packaged_documentation():
|
|
55
|
+
for line_number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
|
|
56
|
+
if MAINTAINER_LOCAL_PATH.search(line):
|
|
57
|
+
occurrences.append(f"{path.relative_to(ROOT)}:{line_number}")
|
|
58
|
+
self.assertEqual(occurrences, [], f"maintainer-local paths: {occurrences}")
|
|
59
|
+
|
|
36
60
|
def test_source_readme_uses_portable_absolute_links(self):
|
|
37
61
|
assert_portable(self, (ROOT / "README.md").read_text(encoding="utf-8"))
|
|
38
62
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
ROOT = Path(__file__).parents[1]
|
|
7
|
+
FORBIDDEN = (
|
|
8
|
+
"/Users/" + "smshahinulislam",
|
|
9
|
+
"Developer/" + "scenario-engine-audit",
|
|
10
|
+
"scenario-engine-audit/" + "runtime-venv",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_executable_test_and_ci_surfaces_have_no_maintainer_local_paths():
|
|
15
|
+
paths = list((ROOT / "tests").glob("**/*.py"))
|
|
16
|
+
paths.extend((ROOT / ".github" / "workflows").glob("**/*.yml"))
|
|
17
|
+
paths.extend((ROOT / ".github" / "workflows").glob("**/*.yaml"))
|
|
18
|
+
|
|
19
|
+
occurrences = []
|
|
20
|
+
for path in paths:
|
|
21
|
+
content = path.read_text(encoding="utf-8")
|
|
22
|
+
for forbidden in FORBIDDEN:
|
|
23
|
+
if forbidden in content:
|
|
24
|
+
occurrences.append(f"{path.relative_to(ROOT)}: {forbidden}")
|
|
25
|
+
|
|
26
|
+
assert not occurrences, "maintainer-local paths found:\n" + "\n".join(occurrences)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/compatibility.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/determinism.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/dsl-reference.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/hypothesis.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/quickstart.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/release-process.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/reproducibility.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/schemathesis.md
RENAMED
|
File without changes
|
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/sqlalchemy.md
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/docs/testing-oracle.md
RENAMED
|
File without changes
|
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/cart.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/ecommerce.yaml
RENAMED
|
File without changes
|
{deterministic_scenario_engine-2.1.1 → deterministic_scenario_engine-2.1.2}/examples/openapi.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|