pyplaykit 1.35.0__tar.gz → 1.37.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.
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/CHANGELOG.md +97 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/CLAUDE.md +5 -2
- {pyplaykit-1.35.0/pyplaykit.egg-info → pyplaykit-1.37.2}/PKG-INFO +7 -2
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/README.md +5 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/config.yaml +52 -4
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/CLI_REFERENCE.md +53 -4
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/01_ARCHITECTURE.md +1 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/MCP_SERVER_DESIGN.md +13 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/MULTI_PROJECT_STRUCTURE.md +29 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/OBSERVABILITY.md +6 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_AGENTS_DESIGN.md +73 -4
- pyplaykit-1.37.2/docs/QE_AGENTS_GUIDE.md +279 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_AGENTS_SPIKES.md +58 -4
- pyplaykit-1.37.2/docs/SECRETS_AND_GOVERNANCE.md +389 -0
- pyplaykit-1.37.2/docs/TEST_CREATION_PLAYGROUND.md +269 -0
- pyplaykit-1.37.2/docs/adr/0017-agent-evaluation-baseline-then-threshold.md +57 -0
- pyplaykit-1.37.2/docs/adr/0018-change-intelligence-without-product-source.md +93 -0
- pyplaykit-1.37.2/docs/adr/0019-test-creation-from-test-cases-on-sandbox-branches.md +121 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/README.md +3 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/cli.py +14 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/server.py +17 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/agent_tools.py +21 -3
- pyplaykit-1.37.2/orchestration/selection.py +160 -0
- pyplaykit-1.37.2/pyplaykit/agents/audit.py +182 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/budgets.py +1 -1
- pyplaykit-1.37.2/pyplaykit/agents/builtin/__init__.py +1 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/_common.py +39 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/__init__.py +1 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/agent.py +322 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/agent.yaml +29 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/impact.py +256 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/prompts/change_semantics.md +22 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/prompts/regression_additions.md +19 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/risk.py +147 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/schemas/input.json +12 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/schemas/output.json +69 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/change_intelligence/selection.py +180 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/__init__.py +1 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/agent.py +478 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/agent.yaml +31 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/assemble.py +303 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/layout.py +107 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/prompts/generate_tests.md +30 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/prompts/guide_api.md +11 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/prompts/guide_db.md +11 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/prompts/guide_device.md +10 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/prompts/guide_ui.md +20 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/schemas/input.json +15 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/schemas/output.json +24 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_creation/testcases.py +259 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/__init__.py +1 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/agent.py +199 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/agent.yaml +28 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/prompts/test_intent.md +18 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/rules.py +320 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/schemas/input.json +12 -0
- pyplaykit-1.37.2/pyplaykit/agents/builtin/test_review/schemas/output.json +29 -0
- pyplaykit-1.37.2/pyplaykit/agents/cli.py +515 -0
- pyplaykit-1.37.2/pyplaykit/agents/enforcement.py +225 -0
- pyplaykit-1.37.2/pyplaykit/agents/host_tools.py +337 -0
- pyplaykit-1.37.2/pyplaykit/agents/impact_map.py +411 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/recording.py +3 -2
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/routing.py +20 -7
- pyplaykit-1.37.2/pyplaykit/agents/output.py +83 -0
- pyplaykit-1.37.2/pyplaykit/agents/policy.py +331 -0
- pyplaykit-1.37.2/pyplaykit/agents/read_tools.py +376 -0
- pyplaykit-1.37.2/pyplaykit/agents/redaction.py +254 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/runner.py +313 -15
- pyplaykit-1.37.2/pyplaykit/agents/sandbox.py +445 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/session.py +3 -2
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/settings.py +111 -24
- pyplaykit-1.37.2/pyplaykit/agents/stacks/__init__.py +94 -0
- pyplaykit-1.37.2/pyplaykit/agents/stacks/base.py +183 -0
- pyplaykit-1.37.2/pyplaykit/agents/stacks/environment.py +150 -0
- pyplaykit-1.37.2/pyplaykit/agents/stacks/junit.py +87 -0
- pyplaykit-1.37.2/pyplaykit/agents/stacks/python_pytest.py +372 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/telemetry.py +24 -6
- pyplaykit-1.37.2/pyplaykit/agents/tools.py +145 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/cli.py +72 -16
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/config/config.yaml +52 -4
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/CLI_REFERENCE.md +53 -4
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/MCP_SERVER_DESIGN.md +13 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/MULTI_PROJECT_STRUCTURE.md +29 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/OBSERVABILITY.md +6 -0
- pyplaykit-1.37.2/pyplaykit/docs/QE_AGENTS_GUIDE.md +279 -0
- pyplaykit-1.37.2/pyplaykit/docs/SECRETS_AND_GOVERNANCE.md +389 -0
- pyplaykit-1.37.2/pyplaykit/docs/TEST_CREATION_PLAYGROUND.md +269 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/api_posts.csv +8 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/custom_columns.csv +7 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/db_employees.csv +11 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/device_thermostat.csv +12 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/mixed_checkout.csv +13 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/steps_per_row.csv +7 -0
- pyplaykit-1.37.2/pyplaykit/docs/examples/testcases/ui_login.csv +21 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/plugin.py +16 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2/pyplaykit.egg-info}/PKG-INFO +7 -2
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit.egg-info/SOURCES.txt +62 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit.egg-info/entry_points.txt +3 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit.egg-info/requires.txt +1 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyproject.toml +7 -2
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/spikes/qe_agents/README.md +2 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/dashboard.py +69 -23
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/observability.py +22 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/org_governance.py +112 -13
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secret_redaction.py +4 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/__init__.py +24 -1
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/telemetry_schema.py +2 -0
- pyplaykit-1.35.0/docs/SECRETS_AND_GOVERNANCE.md +0 -241
- pyplaykit-1.35.0/pyplaykit/agents/cli.py +0 -187
- pyplaykit-1.35.0/pyplaykit/docs/SECRETS_AND_GOVERNANCE.md +0 -241
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/.github/copilot-instructions.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/.github/prompts/review-execution-plan-and-implement-next-task.prompt.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/.github/prompts/run-unit-tests-and-coverage.prompt.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/.github/prompts/security-audit-and-consolidated-report.prompt.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/CHOOSE_YOUR_STRUCTURE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/COLUMN_MAPPING_AND_IGNORE_FIELDS_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/COMMANDS_FOR_YOUR_PROJECTS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/COMMIT_SUMMARY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/CONTRIBUTING.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/CORRECTED_PROJECT_NAMES.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/DATABASE_IMPLEMENTATION_SUMMARY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/DELIVERABLES_SUMMARY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/ENTERPRISE_TEST_STRUCTURE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/FINAL_PROJECT_SETUP.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/GAP_TRACKER.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/HOW_TO_ACCESS_DOCS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/INIT_COMMAND_EXAMPLES.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/KEY_BASED_MATCHING_SOLUTION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/MANIFEST.in +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/MIGRATION_COMPLETE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/MIGRATION_PLAN.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/PYPLAYKIT_CLIENT_OVERVIEW.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/QUICK_DB_REFERENCE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/QUICK_REFERENCE_COMPARISON_FEATURES.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/QUICK_START_QE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/STRUCTURE_COMPARISON.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/TEST_LOCATION_CHEATSHEET.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/VISUAL_COMPARISON.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/WINDOWS_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/YOUR_SETUP_SUMMARY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/bin/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/components/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/components/base_component.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/components/data_table.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/components/form_field.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/components/modal.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/data_comparison_profiles.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/devices.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/environments.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/projects/device_lab.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/base_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/base_test.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/browser_factory.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/playwright_manager.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/core/quality_gate.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/data_validation_dashboard.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/docker-compose.yml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/engineering_dashboard.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/executive_qe_dashboard.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/grafana-provisioning/dashboards/pyplaykit.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/prometheus.yml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/release_quality_dashboard.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dashboards/test_health_dashboard.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/demo/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/demo/device_lab/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/demo/functional/database/file_comparison/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/demo/functional/database/postgres_src_tgt/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dist_pkg/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/dist_pkg/distribution.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/API_TESTING_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/ARCHITECTURE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/CI_INTEGRATION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/COMPETITIVE_ANALYSIS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/COVERAGE_IMPROVEMENTS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/CUSTOMER_SCENARIOS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/DATABASE_SUPPORT.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/DATA_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/DELIVERABLES_INDEX.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/DEVICE_AUTOMATION_WBS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/EXAMPLE_TESTS_SUMMARY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/Enterprise-Framework-Assessment-REVISED.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/Enterprise-Readiness-Assessment.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/Example-Tests-Guide.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/Execution-Plan-Backlog-and-Closure-Tracker.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/FRAMEWORK_CONTRIBUTION_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/02_DEPLOYMENT_RUNBOOK.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/03_ACCESS_MATRIX.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/04_CLIENT_CONTACT_MATRIX.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/05_OPEN_RISKS_REGISTER.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/06_PENDING_ENHANCEMENTS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/07_PRODUCT_ROADMAP.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/08_ENVIRONMENT_DETAILS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/09_OPERATIONAL_SOPS.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/10_ESCALATION_MATRIX.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/11_KT_RECORDINGS_INDEX.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/12_REVERSE_KT_SIGNOFF.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/13_LEADERSHIP_SIGNOFF.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/KT/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/MULTI_DB_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/PLUGIN_AUTHORING_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/PyPlayKit-Framework-Overview.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/PyPlayKit-Usage-Scenarios.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_AGENTS_CAPABILITY_INVENTORY.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_AGENTS_THREAT_MODEL.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_AGENT_PLATFORM_EXPANSION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QE_VISUAL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/QUALITY_GATE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/RESILIENCE_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/RUN_TESTS_QUICK_REFERENCE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/TEST_ORGANIZATION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/Usage-Scenarios-Feasibility-Analysis.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0001-sync-device-api-with-background-io.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0002-devices-subpackage-and-layering.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0003-dut-naming-for-cli-config-and-fixtures.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0004-optional-dependencies-and-import-guards.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0005-single-source-device-pytest-plugin.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0006-agent-runtime-transport.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0007-agent-autonomy-and-scm-boundaries.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0008-agent-contract-and-versioning.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0009-host-mediation-and-enforcement-model.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0010-target-stack-adapters-and-result-normalization.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0011-generation-capability-registry.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0012-regression-test-selection-safety.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0013-agent-telemetry-and-data-handling.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0014-agents-adopt-vs-build.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0015-agent-release-lifecycle-and-registry.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/adr/0016-review-driven-amendments.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/device_automation/DESIGN.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/device_automation/GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/docs/device_automation/SPIKES.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/integrations/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/integrations/adapters.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/_ast_utils.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/_config_utils.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/device_tools.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/package_discovery.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/project_introspection.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/mcp_server/tools/project_state.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/orchestration/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/orchestration/enforcer.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/orchestration/planner.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/dashboard_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/login_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/orangehrm_login_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/saucedemo_inventory_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pages/saucedemo_login_page.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/_observer.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/_reference.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/api_plugin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/base.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/data_plugin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/manifest.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/registry.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/plugins/security_plugin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/__main__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/contract.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/errors.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/anthropic.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/base.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/cache.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/fake.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/ollama.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/openai_compat.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/llm/pricing.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/registry.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/reports.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/schemas/1/agent-manifest.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/schemas/1/change-proposal.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/schemas/1/run-result.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/agents/schemas/1/task-envelope.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/config/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/config/devices.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/config/environments.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/_extras.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/assertions.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/buffer.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/candb.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/channel.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/clock.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/commands.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/components.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/config.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/console.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/device.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/editor.html +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/editor.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/errors.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/events.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/factory.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/fault_proxy.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/faults.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/fidelity.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/gatt.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/introspect.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/inventory.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/leasing.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/matching.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/messages.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/parsers.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/pool.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/power.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/provider.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/pytest_plugin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/recording.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/recovery.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/registers.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/ble.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/components.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/base.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/ble.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/can.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/http.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/modbus.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/mqtt.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/serial.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/endpoints/ssh.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/host.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/modbus.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/replay.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/scheduler.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/seed.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/sensor_faults.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/serve.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/signals.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/subprocess_twin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/templating.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/energy_meter.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/engine.dbc +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/engine_ecu.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/environment_sensor.yaml +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/heart_rate.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/smart_plug.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/twins/thermostat.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/sim/yaml_twin.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/snmp.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/terminal.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/testing.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transcript.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transport.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/_async_bridge.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/adb.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/ble.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/can.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/coap.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/http.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/modbus.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/mqtt.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/serial.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/ssh.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/transports/telnet.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/waiting.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/devices/yamlutil.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/API_TESTING_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/ARCHITECTURE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/CI_INTEGRATION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/DATABASE_SUPPORT.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/DATA_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/PLUGIN_AUTHORING_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/QE_VISUAL_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/QUICK_START_QE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/RESILIENCE_GUIDE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/RUN_TESTS_QUICK_REFERENCE.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/docs/TEST_ORGANIZATION.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/extras.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit/show_docs.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit.egg-info/dependency_links.txt +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/pyplaykit.egg-info/top_level.txt +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/resilience/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/resilience/locator_recovery.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/setup.cfg +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/spikes/device_automation/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/api/ecom/auth_payloads.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/api/ecom/product_payloads.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/api_test_data.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/data_validation_test_data.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/login_test_data.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/orangehrm_login_data.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/pacts/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/test_data/ui_test_data.json +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/customs_modernization/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/demo/functional/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/demo/functional/api/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/demo/functional/database/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/demo/functional/ui/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/demo/integration/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/dispatcho/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/tests/projects/timelyquote/README.md +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/api_client.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/api_test_helper.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/assertion_helper.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/auth_manager.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/comparison_config_loader.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/contract/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/contract/pact_consumer.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/data_comparison_report.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/data_comparison_utils.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/data_loader.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/data_source.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/data_validator.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/database_clients.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_client.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/__init__.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/db2.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/informix.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/mongodb.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/mysql.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/oracle.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/snowflake.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/sqlite.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_drivers/sqlserver.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_factory.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_fixtures.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_pool.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/db_validation_helper.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/environment_validator.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/file_reader.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/governance.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/graphql_client.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/logger.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/observability_report.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/project_config.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/response_validator.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/screenshot_helper.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/aws_provider.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/azure_provider.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/base.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/env_provider.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/secrets/vault_provider.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/soap_client.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/tdm.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/telemetry.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/transformation_validator.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/ui_db_validator.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/version_checker.py +0 -0
- {pyplaykit-1.35.0 → pyplaykit-1.37.2}/utils/yaml_config_reader.py +0 -0
|
@@ -11,6 +11,103 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [1.37.2] — 2026-10-11
|
|
15
|
+
|
|
16
|
+
`test-creation` can now commit generated tests to a feature branch of your sandbox repository and push that branch for you to validate and raise as a pull request; a hands-on playground with sample CSVs ships with the package (`pyplaykit docs test-creation`); scaffolded projects no longer break without pandas. Agents stay **disabled by default**, and branch mode needs `agents.autonomy.max: branch` plus `--autonomy branch`.
|
|
17
|
+
|
|
18
|
+
### Behaviour changes — check before upgrading
|
|
19
|
+
|
|
20
|
+
- **Test runs started by agents no longer receive `PYPLAYKIT_SANDBOX_*` variables** (they hold the sandbox push token). *What to do:* nothing, unless a test reads such a variable; rename it.
|
|
21
|
+
- **`agents.scm.sandbox` is a new config block** (empty `repo` by default). Projects that copy `config/config.yaml` by hand can add it from a fresh `pyplaykit init`; without it the defaults apply.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Test creation playground (`pyplaykit docs test-creation`).** A hands-on guide from a fresh `pip install` + `pyplaykit init` project: skeletons without a model, real tests with a model, sandbox feature branches, CSV format, settings and troubleshooting. Seven sample CSVs ship with the package (UI, API with inferred types, database, device, mixed, one row per step, custom column names); `pyplaykit docs <topic> --save-examples [DIR]` copies them (default `test_data/testcases/`, never overwrites).
|
|
26
|
+
- **Sandbox feature branches for `test-creation` (ADR-0019 amendment 1, US-AG12.3.3).** With `--autonomy branch` and `agents.scm.sandbox.repo` set, `pyplaykit agents run test-creation` clones the sandbox repository, creates `feature/test-creation/<csv>-<UTC time>` from `origin/main`, generates the tests against that repository's layout, validates them (`pytest --collect-only`; device tests in sim mode), commits them with the test-case CSV as the engineer, and pushes only the feature branch. It never opens a pull request or touches `main`: the engineer validates and edits the tests and opens the pull request. The push token comes from `PYPLAYKIT_SANDBOX_GIT_TOKEN` (environment or `.env`) and reaches git only as an HTTP header; test runs never receive it. New `agents.scm.sandbox` settings; one `sandbox_branch` audit record per run.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **Scaffolded data-comparison demos without pandas.** In a project created by `pyplaykit init` on a plain `pip install pyplaykit`, `test_demo_excel.py` broke test collection (`No module named 'pandas'`) and the file-comparison demos failed. They now skip with `pip install "pyplaykit[data-comparison]"`; `init` names the same extra when it skips the demo workbooks. Existing projects: re-run `pyplaykit init` does not replace existing files; copy the new guard from a fresh scaffold or install the extra.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [1.37.1] — 2026-10-11
|
|
35
|
+
|
|
36
|
+
First release on PyPI of the QE agents Phase 1 work: the v1.37.0 tag was not published because its CI gate failed on three agent unit tests under `CI=true`. 1.37.1 contains everything in [1.37.0] below, plus two new built-in agents, `test-review` and `test-creation`. Agents stay **disabled by default**.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **Built-in agent `test-creation` (ADR-0019, US-AG12.3.1-3.2).** Turns test cases from a CSV (id, name, description, objective, steps, expected results; optional type, feature, tags) into PyPlayKit UI, API, database and device tests in the project's `pyplaykit init` layout (`tests/<project>/functional/<type>/<feature>/`), reusing existing page objects and the framework's libraries (`BasePage`, `ApiClient`, `ResponseValidator`, `db_client`, `DbValidationHelper`, `dut`). The host assembles every file; inferred UI locators are marked `UNVERIFIED`; generated code is checked with the test-review rules and fixed by the model up to `fix_attempts`. Output: `test_creation.patch`, `.md` and `.json`; skeletons without a model. Configure under `agents.test_creation`. New read tool `list_files`; `read_source` reports `newline` and `final_newline`.
|
|
41
|
+
- **Built-in agent `test-review` (US-AG17.3.3).** Reviews test code for quality before merge, using only assets the QE team owns: deterministic rules for missing or weak assertions, empty tests, swallowed exceptions, sleeps, hardcoded URLs and credentials, raw selectors in tests, print, skips without a reason, the `tests/functional/<type>/<feature>/` layout, duplicates and parametrize candidates, plus a model review of whether each test checks what it claims. Inputs: a change (`base`/`head`), `paths`, or the whole suite. Outputs `test_review.md` / `test_review.json` and signals (`blocking_issues` counts deterministic high issues only). Configure under `agents.test_review`. Mutation-testing evidence is not included yet.
|
|
42
|
+
- ADR-0018 (accepted): change intelligence without access to product source, planned as EP-AG06 feature 4.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Agent unit tests clear CI-detection and org-governance environment variables, so they behave the same on GitHub Actions as locally (the cause of the failed v1.37.0 publish).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## [1.37.0] — 2026-10-11
|
|
51
|
+
|
|
52
|
+
QE agents Phase 1 complete (Wave 7, EP-AG05 and EP-AG06): the tool layer and Python stack adapter, and the first built-in agent, `change-intelligence` — impact analysis, a deterministic risk score and a regression plan that `pytest --pyplaykit-select-from` applies in PR pipelines. Also the test-impact map, ADR-0017 (evaluation process), the stdio JSON-RPC spike, a QE agents user guide (`pyplaykit docs agents`), and fixes for pip installs. Agents stay **disabled by default**; selection stays off until `agents.change_intelligence.apply_selection` is set on the base branch.
|
|
53
|
+
|
|
54
|
+
### Behaviour changes — check before upgrading
|
|
55
|
+
|
|
56
|
+
These affect only projects that enable agents (`agents.enabled: true`) or write their own agents.
|
|
57
|
+
|
|
58
|
+
- **The host declares data classes on LLM requests.** In an agent run every LLM request now carries `metadata` plus the classes of the tool results the run has received (and any the agent declared). Before, a request the agent did not label counted as carrying every content class. *What to do:* nothing for most agents; an agent that sends content it did not get through a host tool must declare its classes (`pyplaykit.agents.policy.declare`).
|
|
59
|
+
- **Run artifacts are written to disk.** `ctx.artifacts.put()` in a run started by `pyplaykit agents run` or the session trigger writes to `reports/agents/runs/<run id>/artifacts/`; a run reads back only its own artifacts.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- **pip installs without a `config/` folder:** the pytest plugin fell back to `site-packages/config/`, which does not exist, so every test errored with `FileNotFoundError`. It now uses the defaults bundled in the package (`pyplaykit/config/`), as `pyplaykit init` does.
|
|
64
|
+
- **`pyplaykit docs` on Windows consoles and redirected output:** printing emoji under cp1252 raised `UnicodeEncodeError`; output that cannot be encoded is now replaced instead.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **QE agents user guide** (`docs/QE_AGENTS_GUIDE.md`, bundled: `pyplaykit docs agents`): install extras, enabling agents and a model, change-intelligence, the impact map, regression selection in PR pipelines, commands and output files. Verified from a clean `pip install "pyplaykit[agents,mcp]"` outside the repository.
|
|
69
|
+
- **Regression plan and `--pyplaykit-select-from` (US-AG06.3.1, ADR-0012).** `change-intelligence` writes `regression_plan.json`: `must_run` (tests mapped to the change, changed test files, smoke tests), `should_run` (importing test files, co-failing tests, and tests the model adds, which it can only add) and `safe_to_skip`, each with reasons; or `full_suite` with the reasons (infrastructure or config change, shared code, untrusted or old map, low confidence). `pytest --pyplaykit-select-from <plan|latest>` deselects only safe-to-skip tests, only in PR pipelines with `agents.change_intelligence.apply_selection` (off by default) true on the base branch, at the plan's commit. In PR pipelines the impact map comes from `PYPLAYKIT_IMPACT_MAP` or the base branch, and the agent's settings from the base branch (F7). `max_map_age` accepts durations such as `7d`.
|
|
70
|
+
- **Deterministic risk score (US-AG06.2.2).** `change-intelligence` scores every changed file 0-100 from change type, code-area criticality, coverage gap, size, failure history and blast radius, with a tier and each factor's contribution and reason; the overall score is the riskiest file's. Configure under `agents.change_intelligence.risk` (weights, thresholds, `criticality.areas`). New signals: `risk_score`, `risk_tier`, `high_risk_files`.
|
|
71
|
+
- **`ctx.settings`**: an agent reads its own `agents.<agent_name>` block (after org governance, read-only); policy keys such as `llm` or `budgets` are never exposed this way. `get_test_impact_map` for files also returns `total_tests`, `failures` and `history`.
|
|
72
|
+
- **First built-in agent: `change-intelligence`, impact analysis (US-AG06.2.1).** For a commit range it lists each changed file's area, the functions it touches, the tests mapped to them, untested changed code, features, API domains and requirement ids from test docstrings, and asks the model what each change means through a structured-output prompt; without a model the deterministic impact is still returned (`partial`). Writes `impact.json` and `impact.md` run artifacts. Runs at `recommend` at most, and only when `agents.enabled` (off by default). Example: `pyplaykit agents run change-intelligence --input '{"base": "origin/main"}'`.
|
|
73
|
+
- **`ctx.prompt(name, **values)`**: agents load prompts from their own `prompts/` directory; the prompt's SHA-256 is recorded in the run events and the audit log. Projects cannot override agent prompts.
|
|
74
|
+
- **Test-impact map (US-AG06.1.1).** `pyplaykit/agents/impact_map.py` and `pyplaykit agents impact-map build|show` build `reports/agents/impact_map.json` from per-test coverage (`pytest --cov=<source> --cov-context=test`, mapped to functions and classes), static import dependencies (test → page → module) and the failure history (failure counts, tests that fail together); `--incremental` refreshes it from a partial run and marks changed files stale. `get_test_impact_map` reads the new format. New, off by default: `reporting.history` appends each session's failed tests to `reports/observability/history.jsonl`.
|
|
75
|
+
- **Read tools for agents (US-AG05.1.1).** `HostTools` serves the existing MCP tools agents reuse (redacted by the host's fail-closed redactor, so `get_config` and `get_org_policy` never reach an agent unredacted) and new host-internal read tools in `pyplaykit/agents/read_tools.py`: `get_change_set`, `get_test_impact_map`, `get_failure_artifacts`, `read_source` (confined to the project: symlinks resolved, denylist for `.git/`, `.env*`, keys, `config/org/`, the audit log) and `get_stack_profile`. Tool results carry host-assigned data classes. `HostContext.dispatch()` serves `artifact.put`, `artifact.get` and `log.event`. CLI: `pyplaykit agents tools` and `pyplaykit agents tool <name> [--args JSON]`. None of these tools is exposed by `pyplaykit-mcp`.
|
|
76
|
+
- **Target-stack adapters (US-AG05.2.1, ADR-0010).** `pyplaykit/agents/stacks/`: the `StackAdapter` protocol (`detect`, `conventions`, `run`, `validate_change`), support states per capability, and the `python-pytest` adapter. It detects pytest projects from `pytest.ini`, `pyproject.toml`, `tox.ini`, `setup.cfg` or `conftest.py`, reads the repository's conventions (page objects, locator style, fixtures, assertions, file naming, example files), runs `python -m pytest` with the project's own interpreter and normalises JUnit XML (parsed with `defusedxml`) into results that feed `ObservabilityTracker`. Adapters are discovered through the `pyplaykit.stack_adapters` entry-point group; third-party adapters load only when allowlisted (ADR-0016).
|
|
77
|
+
- **Scrubbed environment for every stack execution (threat model F5).** Runs receive operating-system basics, the target test environment's credentials and `agents.execution.env_passthrough` only; provider and SCM credentials are refused even when listed.
|
|
78
|
+
- `defusedxml` added to the `agents` extra.
|
|
79
|
+
- **Execute tools for agents (US-AG05.1.2).** `pyplaykit/agents/host_tools.py`: `HostTools`, the runner's tool backend (wired by `agent_runner`), serves `run_tests` and `run_single_test` through the stack adapter. Only `agents.execution.allowed_envs` can be targeted; output goes to `reports/agents/runs/<run id>/tests/`, and writes elsewhere are reported in git checkouts; the timeout is capped by the run's deadline. `run_single_test` now counts against the test-execution budget. The runner binds a tool backend that has `for_run(request, envelope)` to each run.
|
|
80
|
+
- The `python-pytest` adapter writes `tmp_path` (`--basetemp`) and coverage data (`COVERAGE_FILE`) to the run's output directory and sets `PYTHONDONTWRITEBYTECODE`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## [1.36.0] — 2026-10-11
|
|
85
|
+
|
|
86
|
+
QE agents governance and safety (Wave 7, EP-AG04): agent policy through org governance, redaction before anything leaves the machine, a tamper-evident audit log, tool tiers with prompt-injection defence, and the enforcement model. Also light and dark themes for the live dashboard, and lock modes for org governance. Agents stay **disabled by default** and no built-in agents ship yet.
|
|
87
|
+
|
|
88
|
+
### Behaviour changes — check before upgrading
|
|
89
|
+
|
|
90
|
+
These affect only projects that enable agents (`agents.enabled: true`) or write their own agents.
|
|
91
|
+
|
|
92
|
+
- **External providers refuse unlabelled requests.** An LLM request that does not declare its data classes (`LLMRequest.metadata["pyplaykit.data_classes"]`, helper `pyplaykit.agents.policy.declare`) counts as carrying source, results, documents and test data, which external providers do not receive by default. *What to do:* declare the classes a request carries, allow them per provider in `agents.llm.egress.<provider>`, or use a provider declared `hosting: self_hosted`. Host-assigned classes for tool results are planned in US-AG05.1.1.
|
|
93
|
+
- **Every LLM request and tool result is redacted** by default, and a request that cannot be redacted safely ends the run `denied`.
|
|
94
|
+
- **Tools are granted by tier.** An agent at `analyze` autonomy no longer gets `execute` tools such as `run_tests`; tools outside the catalogue need `agents.tools.extra`.
|
|
95
|
+
- **Tool calls return `ToolOutput`.** `ctx.tools.call()` returns a `ToolOutput` labelled untrusted; the result is in `.data`.
|
|
96
|
+
- **Runs are audited.** If `reports/agents/audit.jsonl` cannot be written, agent runs are refused.
|
|
97
|
+
- **Agent policy follows org governance.** `agents.*` keys from `config/org/` (and locks) now apply to agent runs; in PR pipelines org policy comes from the base branch or `PYPLAYKIT_ORG_ROOT`.
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
|
|
101
|
+
- **QE agents: policy through org governance** (`pyplaykit.agents.policy`; WBS US-AG04.1.1, ADR-0013, ADR-0016). The `agents:` section now resolves through config, the `config/projects/<project>.yaml` overlay and org → business unit → project governance with locks. `PolicyEnforcer` checks every LLM attempt in the tier router, fallbacks included: provider and model allowlists (`agents.llm.allowed_providers` / `allowed_models`, glob patterns) and the request's data classes against `agents.llm.egress.<provider>` (external providers get `metadata` only by default, providers declared `hosting: self_hosted` get every class but `media` and `secrets`); requests declare classes in `LLMRequest.metadata["pyplaykit.data_classes"]`, and an undeclared request counts as carrying all content classes. MCP-started runs are capped by `agents.mcp.egress`; `agents.execution.allowed_envs` refuses runs targeting other environments (`pyplaykit agents run --env`, the session's `--pyplaykit-env`); in CI, captured content stays out of the uploaded events file unless the new `agents.ci.artifact_classes` covers it. In PR pipelines org policy comes from `PYPLAYKIT_ORG_ROOT` or `config/org/` on the base branch, never the PR head; in CI a missing org root warns, or blocks agent runs with `agents.governance.required` or `PYPLAYKIT_GOVERNANCE_REQUIRED`. New `pyplaykit agents policy` and MCP tool `pyplaykit_get_agent_policy` / `get-agent-policy` (23 tools).
|
|
102
|
+
- **QE agents: enforcement model** (`pyplaykit.agents.enforcement`; WBS US-AG04.5.1, ADR-0009). Every agent control is registered with exactly one class — host-enforced, out-of-process only, or in-process convention — and the story that delivers it (`pyplaykit agents controls`). An `ast` scan checks in-process agent code for the convention (no provider SDKs, `subprocess` / test runners, git libraries, `httpx` / `requests` / `urllib`, `open` or path file access, `os.environ`, `importlib`, `__import__`, `eval`): `pyplaykit agents scan [PATH…]` exits 1 on findings, and the unit tests run it over the built-in agents, so a breach fails CI. The docs state that in-process is not a sandbox.
|
|
103
|
+
- **QE agents: tool tiers and prompt-injection defence** (`pyplaykit.agents.tools`, `pyplaykit.agents.output`; WBS US-AG04.4.1, threat model TH5, F13). Tools are granted by permission tier (`read`, `execute`, `propose`) according to the effective autonomy (`analyze` → read; `recommend` → read and execute; `propose`+ → all), narrowed by `agents.tools.allowed_tiers`; tools outside the catalogue are refused unless `agents.tools.extra` declares their tier, and refused tools appear as run warnings and in the `run.started` event. Tool results reach the agent redacted (fails closed) and wrapped as `ToolOutput` labelled untrusted, whose `as_prompt()` block cannot be closed by its content; a prompt-injection corpus test shows injected text cannot change the run's tools or autonomy. Model-generated text is encoded per sink (`encode(text, "markdown" | "html" | "mcp" | "terminal")`, `model_generated()`): raw HTML and images stripped, @-mentions neutralised, links only to `agents.output.allowed_link_domains`, terminal control sequences removed; MCP `run_agent` responses and CLI run output use it. Artifacts are limited to allowed content types and sizes (`agents.artifacts`), need plain names, and archives are refused by signature. Behaviour change: an agent calling a tool now receives a `ToolOutput` (its data in `.data`) instead of the raw result.
|
|
104
|
+
- **QE agents: tamper-evident audit log** (`pyplaykit.agents.audit`; WBS US-AG04.3.1, threat model F15, TH32). `reports/agents/audit.jsonl` is append-only and hash-chained: the runner records each run's start (trigger, actor, agent, version, release digest, autonomy, environment, effective-policy hash), every LLM call (model, tokens, cost, redaction count, request SHA-256), every tool call (arguments SHA-256, status), every change proposal (diff SHA-256) and the outcome, with no prompt, argument or diff content. People are recorded by user id (`PYPLAYKIT_USER_ID`, the CI actor, else the login); e-mail-like ids are pseudonymised. A run whose actions cannot be audited is stopped with `policy_denied`. New `pyplaykit agents audit verify|head` (verify exits 1 on a broken chain), `pyplaykit agents decide <proposal> accept|reject` (audit log, run log and telemetry) and `pyplaykit agents prune` (run log, audit log with `agents.retention.audit_days`, response cache; pruning keeps the chain verifiable). The Jenkins and Azure DevOps templates print the audit chain head in the job log and upload the audit log; `python -m pyplaykit.agents.cli` runs the agents CLI without the console script.
|
|
105
|
+
- **QE agents: redaction before anything leaves the machine** (`pyplaykit.agents.redaction`; WBS US-AG04.2.1, ADR-0013). Every LLM request is redacted in the runner before it is sent: known secret values (every `${SECRET:…}` value the process resolved, recorded in the new `utils.secrets.resolved_secret_values()` registry; environment variables on `agents.redaction.env_allowlist`, matching `agents.redaction.env_patterns` or with secret-looking names; credentials in `environments.yaml`), credential and PII patterns (private keys, AWS keys, GitHub and Slack tokens, JWTs, bearer tokens, URL passwords, e-mail, Luhn-checked card numbers, phone numbers, plus `agents.redaction.patterns`) and sensitive `key=value` / JSON fields (TDM masking rules). It fails closed: an error, or a credential still present after masking, refuses the call with `policy_denied`. Redaction counts are recorded on `chat` and run spans (`pyplaykit.redactions`), and captured telemetry content uses the same redactor. `AgentRunner` redacts by default (`redactor=None` only for tests).
|
|
106
|
+
- **Org governance: lock modes.** `policy.locked_keys` entries may be `{key, mode}` with `pin` (the default, as before), `min` (floor), `max` (ceiling) or `raise_only` (lists keep org entries, maps keep and may raise them); numbers, versions, autonomy levels and risk tiers are ordered, and an incomparable value falls back to the org value. Resolution entries record the lock mode and org value.
|
|
107
|
+
- **Live dashboard: light and dark themes.** The dashboard follows the operating system's theme, and a **Light / Dark** button in the header switches it; the choice is remembered in that browser (`localStorage`). Tables scroll inside their section on narrow screens.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
14
111
|
## [1.35.0] — 2026-10-11
|
|
15
112
|
|
|
16
113
|
QE agents observability (Wave 7, EP-AG03): GenAI traces, agent metrics and events, and a run log with reports, usage CLI and MCP tools. Agents stay **disabled by default** and no built-in agents ship yet; existing suites are unaffected. Tracing needs `telemetry.enabled` (the `telemetry` extra for OTLP export); Prometheus export needs the `prometheus` extra.
|
|
@@ -13,6 +13,7 @@ For QE engineers adding functional tests, see:
|
|
|
13
13
|
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Comprehensive contributor guide
|
|
14
14
|
- **[docs/QE_VISUAL_GUIDE.md](docs/QE_VISUAL_GUIDE.md)** - Visual guide with diagrams
|
|
15
15
|
- **[docs/TEST_ORGANIZATION.md](docs/TEST_ORGANIZATION.md)** - Enterprise-scale test organization
|
|
16
|
+
- **[docs/QE_AGENTS_GUIDE.md](docs/QE_AGENTS_GUIDE.md)** - QE agents user guide (also `pyplaykit docs agents` after pip install)
|
|
16
17
|
|
|
17
18
|
Quick answer: Add UI tests to `tests/functional/ui/<feature>/`, API tests to `tests/functional/api/<domain>/`, database tests to `tests/functional/database/<category>/`, and integration tests to `tests/integration/`.
|
|
18
19
|
|
|
@@ -102,9 +103,10 @@ Available pytest CLI options (registered in `conftest.py`):
|
|
|
102
103
|
- `--pyplaykit-dut-mode` — Device automation mode: sim (twins, default), emu (not yet available), hil (real hardware); or PYPLAYKIT_DUT_MODE
|
|
103
104
|
- `--pyplaykit-bench` — Device bench whose DUTs are in scope (config/devices.yaml benches); or PYPLAYKIT_BENCH
|
|
104
105
|
- `--pyplaykit-dut` — DUT for tests that do not select one with `requires_dut`; or PYPLAYKIT_DUT
|
|
106
|
+
- `--pyplaykit-select-from` — Apply a change-intelligence regression plan (`regression_plan.json` or `latest`): deselect only tests it marks safe to skip, in PR pipelines with `agents.change_intelligence.apply_selection` on the base branch; or PYPLAYKIT_SELECT_FROM
|
|
105
107
|
- `--pyplaykit-agents` — After the session, run the agents in `agents.triggers.on_session_finish` (local only; skipped in CI; requires `agents.enabled`)
|
|
106
108
|
|
|
107
|
-
QE agents CLI: `pyplaykit agents [--config DIR] [--json] list | show <agent> | run <agent> [--input JSON|FILE] [--stack S] [--autonomy LEVEL] [--project P] | usage [--by agent|model|project|day] [--days N]` (disabled by default — `agents.enabled: false` in `config/config.yaml`; `run` exits 0 only on success; see docs/QE_AGENTS_DESIGN.md).
|
|
109
|
+
QE agents CLI: `pyplaykit agents [--config DIR] [--json] list | show <agent> | run <agent> [--input JSON|FILE] [--stack S] [--autonomy LEVEL] [--project P] | usage [--by agent|model|project|day] [--days N] | policy [--project P] [--business-unit B] | audit verify|head | decide <proposal> accept|reject --agent A | prune | controls | scan [PATH...] | impact-map build|show [--coverage FILE] [--incremental] | tools | tool <name> [--args JSON] [--env E]` (`run` also takes `--env E`) (disabled by default — `agents.enabled: false` in `config/config.yaml`; `run` exits 0 only on success; see docs/QE_AGENTS_DESIGN.md).
|
|
108
110
|
|
|
109
111
|
Device bench CLI: `pyplaykit devices [--config DIR] [--env ENV] [--bench B] [--mode M] list | show <dut> | check | scenarios | report | catalog [--json] | release <dut> | editor [--serve]` (`check` exits 1 when a DUT is not ready; `--json` output matches the MCP device tools; `editor` edits devices.yaml through forms in a self-contained HTML page, `--serve` saves it directly).
|
|
110
112
|
- `pyplaykit devices list|release <dut>` — Device bench inventory (capabilities, leases, quarantine)
|
|
@@ -264,7 +266,7 @@ Defined in `pytest.ini`:
|
|
|
264
266
|
|
|
265
267
|
**Wave 4 (In Progress):** Self-healing locators with fallback chains and DOM retries (complete), distribution packaging baseline (complete), semantic versioning governance (pending)
|
|
266
268
|
|
|
267
|
-
**Wave 5 (Complete):** MCP server for AI interoperability —
|
|
269
|
+
**Wave 5 (Complete):** MCP server for AI interoperability — 23 tools across 5 categories (package discovery, project introspection, project state, device automation, QE agents), all also exposed as CLI subcommands. All are read-only except `check_bench_readiness` (connects DUTs, runs health probes). See `docs/MCP_SERVER_DESIGN.md`.
|
|
268
270
|
|
|
269
271
|
**Wave 6 (Complete):** Enterprise readiness gap closure — expanded DB assertions (assert_date_range/aggregate/schema_match), ApiClient OAuth2/multipart/cookie extensions, WCAG accessibility testing, mobile device emulation, Jenkins/Azure DevOps CI templates, Quality Gate Engine (PASS/WARN/BLOCK verdicts)
|
|
270
272
|
|
|
@@ -318,6 +320,7 @@ Every tool is available in two ways: as an **MCP tool** (for AI assistants) and
|
|
|
318
320
|
| `pyplaykit_check_bench_readiness` | `check-bench-readiness [--bench] [--mode] [--dut]` | Device Automation | Connect each DUT, run health probes, disconnect (exit 1 when not ready) |
|
|
319
321
|
| `pyplaykit_run_agent` | `run-agent <agent> [--input JSON] [--autonomy analyze\|recommend]` | QE Agents | Run a QE agent at analyze/recommend only (requires `agents.enabled`) |
|
|
320
322
|
| `pyplaykit_list_agents` | `list-agents` | QE Agents | Discovered agents, whether config lets each run, refused agents |
|
|
323
|
+
| `pyplaykit_get_agent_policy` | `get-agent-policy [--project] [--business-unit]` | QE Agents | Effective agent policy after org governance: source, locks, egress per provider |
|
|
321
324
|
| `pyplaykit_get_agent_usage` | `get-agent-usage [--days N] [--by agent\|model\|project\|day]` | QE Agents | Runs, tokens and cost from `reports/agents/runs.jsonl` |
|
|
322
325
|
|
|
323
326
|
### CLI usage examples
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyplaykit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.37.2
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -61,6 +61,7 @@ Provides-Extra: mcp
|
|
|
61
61
|
Requires-Dist: mcp<2,>=1.2; extra == "mcp"
|
|
62
62
|
Provides-Extra: agents
|
|
63
63
|
Requires-Dist: jsonschema>=4.0; extra == "agents"
|
|
64
|
+
Requires-Dist: defusedxml>=0.7; extra == "agents"
|
|
64
65
|
Provides-Extra: agents-anthropic
|
|
65
66
|
Requires-Dist: anthropic<2,>=1.0; extra == "agents-anthropic"
|
|
66
67
|
Provides-Extra: agents-openai
|
|
@@ -193,7 +194,7 @@ PyPlayKit is a **multi-project enterprise test automation framework** built with
|
|
|
193
194
|
- 🔍 **Self-Healing**: Locator recovery with fallback chains
|
|
194
195
|
- 🔭 **Observable**: Comprehensive metrics and reporting
|
|
195
196
|
- 📟 **Device & Embedded Automation**: Test IoT / embedded / PLC / CAN / BLE / Android devices against digital twins or real hardware ⭐ **NEW**
|
|
196
|
-
- 🤖 **AI-ready**: MCP server with
|
|
197
|
+
- 🤖 **AI-ready**: MCP server with 23 tools, each also a `pyplaykit-mcp` CLI subcommand
|
|
197
198
|
|
|
198
199
|
---
|
|
199
200
|
|
|
@@ -1018,6 +1019,10 @@ Each project config includes:
|
|
|
1018
1019
|
**Wave 7** 🚧 In progress — QE agents (change intelligence, coverage and test design, test creation, execution intelligence): see [design](docs/QE_AGENTS_DESIGN.md), [plan](docs/QE_AGENTS_PLAN.html) and ADRs 0006–0016 in [docs/adr/](docs/adr/README.md).
|
|
1019
1020
|
- Done so far (Phase 1, disabled by default): versioned agent contract and JSON Schemas, agent discovery with digest pinning, the runner (limits, effective autonomy, typed results), the `agents:` config block, `pyplaykit agents list | show | run`, `--pyplaykit-agents` (local only) and the MCP `run_agent` tool.
|
|
1020
1021
|
- GenAI spans for agent runs, LLM and tool calls (OpenTelemetry GenAI conventions), content capture off by default; `agent.*` events and `pyplaykit_agent_*` Prometheus metrics (tokens, cost, latency, tool calls, budget breaches, proposals); `reports/agents/runs.jsonl` and `usage_summary.json`, agent sections in the persona reports, a dashboard panel, `pyplaykit agents usage` and the MCP `list_agents` / `get_agent_usage` tools
|
|
1022
|
+
- v1.37.0: Phase 1 complete — tool layer and Python stack adapter, the test-impact map, and the first built-in agent `change-intelligence` (impact, risk score, regression plan applied with `--pyplaykit-select-from` in PR pipelines); user guide: `pyplaykit docs agents`
|
|
1023
|
+
- v1.37.1: first PyPI release of Phase 1 (v1.37.0 was not published), plus built-in agents `test-review` (test code quality) and `test-creation` (UI, API, database and device tests from test-case CSVs)
|
|
1024
|
+
- v1.37.2: `test-creation` commits to a feature branch of your sandbox repository and pushes it (never a pull request); hands-on playground with sample CSVs (`pyplaykit docs test-creation --save-examples`); scaffold demos skip without pandas
|
|
1025
|
+
- v1.36.0: agent governance and safety — policy through org governance, redaction, audit log, tool tiers, enforcement model
|
|
1021
1026
|
- v1.35.0: agent observability — GenAI traces, `agent.*` events and `pyplaykit_agent_*` metrics, run log and reports
|
|
1022
1027
|
- v1.34.0: LLM layer — provider-neutral requests, Anthropic / OpenAI-compatible / Ollama adapters, fake and record/replay clients, model tiers with fallback and retries, budgets, cost and a response cache. No built-in agents ship yet.
|
|
1023
1028
|
|
|
@@ -19,7 +19,7 @@ PyPlayKit is a **multi-project enterprise test automation framework** built with
|
|
|
19
19
|
- 🔍 **Self-Healing**: Locator recovery with fallback chains
|
|
20
20
|
- 🔭 **Observable**: Comprehensive metrics and reporting
|
|
21
21
|
- 📟 **Device & Embedded Automation**: Test IoT / embedded / PLC / CAN / BLE / Android devices against digital twins or real hardware ⭐ **NEW**
|
|
22
|
-
- 🤖 **AI-ready**: MCP server with
|
|
22
|
+
- 🤖 **AI-ready**: MCP server with 23 tools, each also a `pyplaykit-mcp` CLI subcommand
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -844,6 +844,10 @@ Each project config includes:
|
|
|
844
844
|
**Wave 7** 🚧 In progress — QE agents (change intelligence, coverage and test design, test creation, execution intelligence): see [design](docs/QE_AGENTS_DESIGN.md), [plan](docs/QE_AGENTS_PLAN.html) and ADRs 0006–0016 in [docs/adr/](docs/adr/README.md).
|
|
845
845
|
- Done so far (Phase 1, disabled by default): versioned agent contract and JSON Schemas, agent discovery with digest pinning, the runner (limits, effective autonomy, typed results), the `agents:` config block, `pyplaykit agents list | show | run`, `--pyplaykit-agents` (local only) and the MCP `run_agent` tool.
|
|
846
846
|
- GenAI spans for agent runs, LLM and tool calls (OpenTelemetry GenAI conventions), content capture off by default; `agent.*` events and `pyplaykit_agent_*` Prometheus metrics (tokens, cost, latency, tool calls, budget breaches, proposals); `reports/agents/runs.jsonl` and `usage_summary.json`, agent sections in the persona reports, a dashboard panel, `pyplaykit agents usage` and the MCP `list_agents` / `get_agent_usage` tools
|
|
847
|
+
- v1.37.0: Phase 1 complete — tool layer and Python stack adapter, the test-impact map, and the first built-in agent `change-intelligence` (impact, risk score, regression plan applied with `--pyplaykit-select-from` in PR pipelines); user guide: `pyplaykit docs agents`
|
|
848
|
+
- v1.37.1: first PyPI release of Phase 1 (v1.37.0 was not published), plus built-in agents `test-review` (test code quality) and `test-creation` (UI, API, database and device tests from test-case CSVs)
|
|
849
|
+
- v1.37.2: `test-creation` commits to a feature branch of your sandbox repository and pushes it (never a pull request); hands-on playground with sample CSVs (`pyplaykit docs test-creation --save-examples`); scaffold demos skip without pandas
|
|
850
|
+
- v1.36.0: agent governance and safety — policy through org governance, redaction, audit log, tool tiers, enforcement model
|
|
847
851
|
- v1.35.0: agent observability — GenAI traces, `agent.*` events and `pyplaykit_agent_*` metrics, run log and reports
|
|
848
852
|
- v1.34.0: LLM layer — provider-neutral requests, Anthropic / OpenAI-compatible / Ollama adapters, fake and record/replay clients, model tiers with fallback and retries, budgets, cost and a response cache. No built-in agents ship yet.
|
|
849
853
|
|
|
@@ -30,6 +30,10 @@ reporting:
|
|
|
30
30
|
engineering_report_path: "reports/observability/engineering_report.json"
|
|
31
31
|
qa_report_path: "reports/observability/qa_functional_report.json"
|
|
32
32
|
leadership_report_path: "reports/observability/leadership_kpi_summary.json"
|
|
33
|
+
history: # per-session failure history; the test-impact map reads it
|
|
34
|
+
enabled: false # for co-failure (US-AG06.1.1); enable in the CI full-suite job
|
|
35
|
+
path: "reports/observability/history.jsonl"
|
|
36
|
+
max_records: 500
|
|
33
37
|
|
|
34
38
|
quality:
|
|
35
39
|
automation_coverage_target: 100
|
|
@@ -302,9 +306,19 @@ agents:
|
|
|
302
306
|
execution:
|
|
303
307
|
allowed_envs: [dev, qa]
|
|
304
308
|
timeout_s: 900
|
|
309
|
+
env_passthrough: [] # extra non-secret variables stack runs receive (globs); provider
|
|
310
|
+
# and SCM credentials are refused even if listed (F5)
|
|
305
311
|
scm:
|
|
306
312
|
protected_branches: [main, master, "release/*"]
|
|
307
313
|
allow_pr: false
|
|
314
|
+
sandbox: # test-creation with --autonomy branch (and autonomy.max: branch)
|
|
315
|
+
repo: "" # repository for feature branches (URL or path); "" = this repository
|
|
316
|
+
base: main # branches start from origin/<base>; never pushed to
|
|
317
|
+
branch_prefix: feature/test-creation
|
|
318
|
+
push: true # push the feature branch only; never a pull request
|
|
319
|
+
token_env: PYPLAYKIT_SANDBOX_GIT_TOKEN # token variable (environment, else .env); sent as a header only
|
|
320
|
+
writable: [tests, pages, test_data]
|
|
321
|
+
workspace: reports/agents/sandbox # clone and worktrees
|
|
308
322
|
telemetry: # GenAI spans need telemetry.enabled (and otlp_endpoint for OTLP)
|
|
309
323
|
capture_content: false # prompts, completions, tool arguments/results; redacted
|
|
310
324
|
otlp_classes: [metadata] # data classes the OTLP endpoint may receive; captured content
|
|
@@ -317,12 +331,46 @@ agents:
|
|
|
317
331
|
governance:
|
|
318
332
|
required: false
|
|
319
333
|
mcp:
|
|
320
|
-
egress: [metadata]
|
|
334
|
+
egress: [metadata] # data classes a run started from an MCP client may send
|
|
335
|
+
redaction: # applied to every LLM request; fails closed (US-AG04.2.1)
|
|
336
|
+
env_allowlist: [] # environment variables whose values are always masked
|
|
337
|
+
env_patterns: ["PYPLAYKIT_TEST_*"] # ... and names matching these (plus secret-looking names)
|
|
338
|
+
patterns: [] # extra [{name, regex}] to mask
|
|
339
|
+
pii: true # e-mail addresses, card numbers, phone numbers
|
|
340
|
+
tools: # tool permission tiers (US-AG04.4.1)
|
|
341
|
+
allowed_tiers: null # e.g. [read, execute]; null: what the autonomy level grants
|
|
342
|
+
extra: {} # tools the catalogue does not know: {name: read | execute | propose}
|
|
343
|
+
artifacts: # what agents may store (threat model F13); archives are never stored
|
|
344
|
+
max_bytes: 5242880
|
|
345
|
+
max_total_bytes: 52428800
|
|
346
|
+
allowed_types: null # null: json, text, markdown, csv, xml/junit, diff, png, jpeg
|
|
347
|
+
output:
|
|
348
|
+
allowed_link_domains: [] # links in model-generated text kept only to these domains
|
|
349
|
+
ci:
|
|
350
|
+
artifact_classes: [metadata] # data classes CI artifact uploads may hold (F21); captured content
|
|
351
|
+
# stays out of the uploaded events file unless they cover it
|
|
321
352
|
change_intelligence:
|
|
322
|
-
min_confidence: null # set from the Phase 2 baseline (ADR-0012)
|
|
323
|
-
max_map_age: null
|
|
353
|
+
min_confidence: null # 0-1; below it the plan is the full suite; set from the Phase 2 baseline (ADR-0012)
|
|
354
|
+
max_map_age: null # seconds or a duration ("36h", "7d"); an older map means the full suite
|
|
324
355
|
shadow_sample_rate: null
|
|
325
|
-
apply_selection: false
|
|
356
|
+
apply_selection: false # kill switch: --pyplaykit-select-from deselects only when true (read from
|
|
357
|
+
# the base branch in PR pipelines; PR pipelines only)
|
|
358
|
+
risk: # deterministic risk score (US-AG06.2.2); weights are normalised
|
|
359
|
+
weights: {change_type: 0.30, criticality: 0.20, coverage_gap: 0.20, size: 0.10, failure_history: 0.10, blast_radius: 0.10}
|
|
360
|
+
thresholds: {medium: 0.35, high: 0.65}
|
|
361
|
+
size_saturation_lines: 200
|
|
362
|
+
criticality:
|
|
363
|
+
default: medium # low | medium | high | critical
|
|
364
|
+
areas: [] # [{paths: ["core/**", "utils/auth*"], level: high}], first match wins
|
|
365
|
+
test_review: # test-review agent (US-AG17.3.3)
|
|
366
|
+
rules: {} # severity per rule: high | medium | low | off, e.g. {print: off, missing-marker: low}
|
|
367
|
+
max_files: 40
|
|
368
|
+
allowed_url_hosts: [] # hosts allowed in test code, e.g. [localhost]
|
|
369
|
+
test_creation: # test-creation agent (ADR-0019)
|
|
370
|
+
max_test_cases: 25
|
|
371
|
+
batch_size: 5 # test cases per model request
|
|
372
|
+
fix_attempts: 2 # problems sent back to the model before a skeleton is kept
|
|
373
|
+
columns: {} # explicit CSV headers, e.g. {id: "TC No", steps: "Procedure"}
|
|
326
374
|
evals:
|
|
327
375
|
export: null
|
|
328
376
|
reports:
|
|
@@ -165,8 +165,10 @@ pyplaykit observability-report --open
|
|
|
165
165
|
Serve the **live execution dashboard** — a zero-dependency, self-contained web
|
|
166
166
|
page that visualizes a test run in real time (or a finished run's `live.jsonl`).
|
|
167
167
|
The page shows collected/run counts, pass/fail/skip totals, current pass rate,
|
|
168
|
-
elapsed time, a per-worker (xdist) breakdown,
|
|
169
|
-
auto-refreshing every second.
|
|
168
|
+
elapsed time, a per-worker (xdist) breakdown, a scrolling recent-test log and, once
|
|
169
|
+
QE agents have run, agent usage, auto-refreshing every second. It follows the operating
|
|
170
|
+
system's light or dark theme; the **Light / Dark** button in the header switches it, and the
|
|
171
|
+
choice is remembered in that browser.
|
|
170
172
|
|
|
171
173
|
```bash
|
|
172
174
|
# Serve the default reports/dashboard/live.jsonl on http://127.0.0.1:7474
|
|
@@ -202,13 +204,32 @@ pyplaykit agents list # discovered agents, and refused
|
|
|
202
204
|
pyplaykit agents show change-intelligence # manifest, launch, digest, autonomy ceiling, may it run
|
|
203
205
|
pyplaykit agents run change-intelligence --input '{"base": "main", "head": "HEAD"}' --autonomy recommend
|
|
204
206
|
pyplaykit agents usage --by model --days 7 # runs, tokens and cost from reports/agents/runs.jsonl
|
|
207
|
+
pyplaykit agents policy --project checkout # effective policy: governance source, locks, egress per provider
|
|
208
|
+
pyplaykit agents audit verify # check the hash-chained audit log (exit 1 when broken)
|
|
209
|
+
pyplaykit agents audit head # print the chain head (CI job logs, threat model F15)
|
|
210
|
+
pyplaykit agents decide cp_12 accept --agent test-creation --run-id agr_… # record a reviewer's decision
|
|
211
|
+
pyplaykit agents prune # apply agents.retention.* to run log, audit log, response cache
|
|
212
|
+
pyplaykit agents controls # every control: host-enforced, out-of-process only, or convention
|
|
213
|
+
pyplaykit agents scan path/to/agent/ # in-process convention scan (exit 1 on findings; default: built-ins)
|
|
214
|
+
pyplaykit agents impact-map build --coverage .coverage # test-impact map from pytest --cov-context=test
|
|
215
|
+
pyplaykit agents impact-map build --incremental --coverage part.cov # refresh with a partial run
|
|
216
|
+
pyplaykit agents impact-map show # summary of reports/agents/impact_map.json
|
|
217
|
+
pyplaykit agents tools # host-internal tools agents can be granted: tier, data classes
|
|
218
|
+
pyplaykit agents tool read_source --args '{"path": "pages/login_page.py", "end": 40}'
|
|
219
|
+
# call a host tool as an agent would (redacted, labelled)
|
|
205
220
|
pyplaykit agents --json list # machine-readable output (any subcommand)
|
|
206
221
|
```
|
|
207
222
|
|
|
208
223
|
**Options:** `--config DIR` (default `config`), `--json`; for `run`: `--input` (JSON object or path to a JSON
|
|
209
224
|
file), `--stack`, `--autonomy` (`analyze` … `pr`; the effective level is the most restrictive of the agent's
|
|
210
|
-
ceiling, `agents.autonomy.max` and this request), `--project
|
|
211
|
-
|
|
225
|
+
ceiling, `agents.autonomy.max` and this request), `--project`, `--env` (the environment the run's tests
|
|
226
|
+
target; refused unless it is in `agents.execution.allowed_envs`); for `policy`: `--project`, `--business-unit`;
|
|
227
|
+
for `impact-map`: `build|show`, `--coverage FILE` (coverage data with per-test contexts), `--history FILE` (default: `reporting.history.path` when the file exists), `--base REF` (default: `HEAD`), `--incremental`, `--output PATH`, `--share-threshold` (default 0.5); for `tool`: `<name> [--args JSON|FILE] [--env E]` (exit 1 when the result has `status: error` or policy refuses the call; no `agents.enabled` needed: it is for people inspecting what agents see); for `audit`: `verify` or `head`, `--path`; for `decide`: `<proposal> accept|reject --agent A [--run-id R] [--by USER]`
|
|
228
|
+
(the reviewer defaults to the current user id: `PYPLAYKIT_USER_ID`, the CI actor, else the login; e-mail
|
|
229
|
+
addresses are pseudonymised); for `usage`: `--by` (`agent`, `model`,
|
|
230
|
+
`project`, `day`; default `agent`), `--days` (default 30). Every run is also written to the hash-chained audit log `reports/agents/audit.jsonl` (run start with
|
|
231
|
+
actor and policy hash, LLM and tool calls as hashes, proposals, outcome, decisions; no prompt or argument
|
|
232
|
+
content), pruned after `agents.retention.audit_days` by `pyplaykit agents prune`. Every run is recorded in `reports/agents/runs.jsonl`
|
|
212
233
|
(input hashed, outcome, usage per model, provenance) and summarised in `reports/agents/usage_summary.json`;
|
|
213
234
|
lines older than `agents.retention.runs_days` (default 90) are pruned.
|
|
214
235
|
|
|
@@ -439,6 +460,18 @@ config lets each run), and agents refused at discovery with the reason. Mirrors
|
|
|
439
460
|
pyplaykit-mcp list-agents
|
|
440
461
|
```
|
|
441
462
|
|
|
463
|
+
##### `get-agent-policy`
|
|
464
|
+
|
|
465
|
+
The effective QE agent policy after org → business unit → project governance: where it came from (in PR
|
|
466
|
+
pipelines the base branch or `PYPLAYKIT_ORG_ROOT`), governance status (`ok` / `warn` / `block`), locks with
|
|
467
|
+
their mode, governed `agents.*` keys, and enforcement as an MCP-started run gets it (allowed providers, models
|
|
468
|
+
and environments, egress per provider, autonomy ceiling). Mirrors `pyplaykit_get_agent_policy`; `error` (exit
|
|
469
|
+
1) when agent runs are blocked or the policy is invalid.
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
pyplaykit-mcp get-agent-policy --project checkout --business-unit payments
|
|
473
|
+
```
|
|
474
|
+
|
|
442
475
|
##### `get-agent-usage`
|
|
443
476
|
|
|
444
477
|
Runs, outcomes, tokens and cost from `reports/agents/runs.jsonl`: the full usage summary, or one grouping.
|
|
@@ -626,6 +659,22 @@ pytest --pyplaykit-orchestration
|
|
|
626
659
|
|
|
627
660
|
---
|
|
628
661
|
|
|
662
|
+
### `--pyplaykit-select-from`
|
|
663
|
+
|
|
664
|
+
Apply a change-intelligence regression plan (`regression_plan.json`, or `latest` for the newest one under
|
|
665
|
+
`reports/agents/runs/`; also `PYPLAYKIT_SELECT_FROM`). Only the tests the plan marks safe to skip are
|
|
666
|
+
deselected, and only when the plan is in selection mode, this is a PR pipeline,
|
|
667
|
+
`agents.change_intelligence.apply_selection` is true on the base branch, and the checkout is the commit the
|
|
668
|
+
plan was made for. Otherwise the full suite runs and one line says why. Smoke tests, tests in changed test
|
|
669
|
+
files and tests the plan does not list always run.
|
|
670
|
+
|
|
671
|
+
```bash
|
|
672
|
+
pyplaykit agents run change-intelligence --input '{"base": "origin/main"}'
|
|
673
|
+
pytest --pyplaykit-select-from latest
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
629
678
|
### `--pyplaykit-project`
|
|
630
679
|
|
|
631
680
|
Active project name override. Loads `config/projects/<name>.yaml`. Overrides auto-detection.
|
|
@@ -44,7 +44,7 @@ projects.
|
|
|
44
44
|
| Dashboard | `utils/dashboard.py` | Live execution dashboard (real-time HTTP UI + JSONL event stream) |
|
|
45
45
|
| Governance | `utils/org_governance.py` | Org → BU → project policy inheritance with locked-key enforcement |
|
|
46
46
|
| Package/CLI | `pyplaykit/` | Public API exports, `pyplaykit` CLI, pytest plugin entry point |
|
|
47
|
-
| MCP Server | `mcp_server/` |
|
|
47
|
+
| MCP Server | `mcp_server/` | 23 MCP tools (incl. 6 device automation tools and the QE agent `run_agent`, `list_agents`, `get_agent_usage` and `get_agent_policy` tools) + CLI subcommands for AI interoperability |
|
|
48
48
|
|
|
49
49
|
The layering rule is enforced by convention: tests never contain raw selectors, page
|
|
50
50
|
objects never contain environment URLs, utilities stay stateless and generic.
|
|
@@ -91,6 +91,19 @@ CLI equivalents: `pyplaykit-mcp get-device-framework | list-devices [--env] [--b
|
|
|
91
91
|
|
|
92
92
|
---
|
|
93
93
|
|
|
94
|
+
### Agent-facing tools are host-internal
|
|
95
|
+
|
|
96
|
+
The QE agent host serves agents more tools than this server exposes (design §2, threat model F6):
|
|
97
|
+
`get_change_set`, `get_test_impact_map`, `get_failure_artifacts`, `read_source`,
|
|
98
|
+
`get_stack_profile`, `run_tests` and `run_single_test`. They are **not** registered by
|
|
99
|
+
`pyplaykit-mcp`, so a connected assistant cannot read source or run tests outside agent policy;
|
|
100
|
+
a unit test checks the server's tool list. When an agent reuses a tool from this catalogue
|
|
101
|
+
(`get_config`, `get_org_policy`, …) the host calls it for the project root and passes the result
|
|
102
|
+
through its fail-closed redactor before the agent sees it. People can call any host tool as an
|
|
103
|
+
agent would with `pyplaykit agents tool <name> [--args JSON]`.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
94
107
|
### Module Registry
|
|
95
108
|
|
|
96
109
|
The following core modules are registered for `get_module_api` / `search_methods` discovery in addition to utility modules. Core modules (prefixed `core.`) are scanned because they contain framework-facing APIs useful to QE engineers and AI assistants.
|
|
@@ -673,6 +673,35 @@ quality_gate:
|
|
|
673
673
|
warn: 0.95
|
|
674
674
|
```
|
|
675
675
|
|
|
676
|
+
#### Lock modes
|
|
677
|
+
|
|
678
|
+
A lock can also bound a value instead of pinning it. Write the entry as a mapping with a
|
|
679
|
+
`mode`:
|
|
680
|
+
|
|
681
|
+
```yaml
|
|
682
|
+
policy:
|
|
683
|
+
locked_keys:
|
|
684
|
+
- quality_gate.enabled # pin (same as {key: ..., mode: pin})
|
|
685
|
+
- {key: agents.autonomy.max, mode: max} # ceiling: lower layers may only lower it
|
|
686
|
+
- {key: agents.budgets.per_run_usd, mode: max}
|
|
687
|
+
- {key: agents.min_contract_version, mode: min} # floor: lower layers may only raise it
|
|
688
|
+
- {key: agents.retention.audit_days, mode: min}
|
|
689
|
+
- {key: agents.risk_overrides, mode: raise_only} # maps: add entries or raise values
|
|
690
|
+
- {key: agents.denied, mode: raise_only} # lists: keep every org entry, add more
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
| Mode | Lower layers may |
|
|
694
|
+
|---|---|
|
|
695
|
+
| `pin` | not change the value |
|
|
696
|
+
| `min` | raise the value, never lower it |
|
|
697
|
+
| `max` | lower the value, never raise it |
|
|
698
|
+
| `raise_only` | add list entries; add map entries or raise their values; raise a scalar |
|
|
699
|
+
|
|
700
|
+
Numbers, versions (`1.1`, `2.0.3`), autonomy levels (`analyze` < `recommend` < `propose` <
|
|
701
|
+
`branch` < `pr`) and risk tiers (`low` < `medium` < `high`) are ordered. A value that cannot be
|
|
702
|
+
compared with the org value is replaced by the org value and logged, so a lock never loosens by
|
|
703
|
+
mistake. `pyplaykit-mcp get-org-policy` shows each lock's mode and the org value.
|
|
704
|
+
|
|
676
705
|
`projects/checkout.yaml` — belongs to the platform BU and sets its own block
|
|
677
706
|
threshold; an attempt to set `quality_gate.enabled: false` here would be
|
|
678
707
|
ignored (the org value wins) and logged:
|
|
@@ -332,3 +332,9 @@ acceptance rate) and **leadership** (spend this month against `agents.budgets.pe
|
|
|
332
332
|
spend by agent, success rate, time saved from `agents.reports.minutes_saved`). The live dashboard
|
|
333
333
|
shows agent usage from `usage_summary.json`; `pyplaykit agents usage` and the MCP
|
|
334
334
|
`get_agent_usage` tool read the same data.
|
|
335
|
+
|
|
336
|
+
**Failure history.** With `reporting.history.enabled: true` (off by default) every pytest session
|
|
337
|
+
appends one line to `reporting.history.path` (default `reports/observability/history.jsonl`): time,
|
|
338
|
+
commit, test count and the failed node ids, keeping the last `max_records` (default 500) sessions.
|
|
339
|
+
The test-impact map reads it for failure counts and tests that fail together
|
|
340
|
+
(`pyplaykit agents impact-map build`); enable it in the CI job that runs the full suite.
|