petfishframework 0.4.2__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- petfishframework-0.5.0/.sisyphus/plans/v0.5.0-plan.md +327 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/CHANGELOG.md +71 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/PKG-INFO +4 -4
- {petfishframework-0.4.2 → petfishframework-0.5.0}/README.md +3 -3
- petfishframework-0.5.0/docs/api-stability.md +88 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/api.md +733 -1
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/skeleton-completeness-checklist.md +34 -23
- {petfishframework-0.4.2 → petfishframework-0.5.0}/pyproject.toml +1 -1
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/__init__.py +1 -1
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/environment.py +207 -8
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/mcp/__init__.py +9 -0
- petfishframework-0.5.0/src/petfishframework/mcp/allowlist.py +20 -0
- petfishframework-0.5.0/src/petfishframework/mcp/client.py +189 -0
- petfishframework-0.5.0/src/petfishframework/mcp/exceptions.py +10 -0
- petfishframework-0.5.0/src/petfishframework/mcp/risk_mapper.py +56 -0
- petfishframework-0.5.0/src/petfishframework/mcp/schema_pin.py +70 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/mcp/stdio_transport.py +10 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/permissions/__init__.py +8 -5
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/permissions/model.py +1 -1
- petfishframework-0.5.0/src/petfishframework/permissions/risk_policy.py +118 -0
- petfishframework-0.5.0/src/petfishframework/tools/__init__.py +28 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/base.py +5 -0
- petfishframework-0.5.0/src/petfishframework/tools/idempotency.py +56 -0
- petfishframework-0.5.0/src/petfishframework/tools/metadata_policy.py +65 -0
- petfishframework-0.5.0/src/petfishframework/tools/rate_limiter.py +74 -0
- petfishframework-0.5.0/src/petfishframework/tools/schema_validator.py +131 -0
- petfishframework-0.5.0/tests/test_mcp_allowlist.py +31 -0
- petfishframework-0.5.0/tests/test_mcp_lifecycle.py +68 -0
- petfishframework-0.5.0/tests/test_mcp_risk_mapping.py +46 -0
- petfishframework-0.5.0/tests/test_mcp_schema_pin.py +60 -0
- petfishframework-0.5.0/tests/test_rate_limiter.py +83 -0
- petfishframework-0.5.0/tests/test_risk_classification.py +117 -0
- petfishframework-0.5.0/tests/test_tool_idempotency.py +72 -0
- petfishframework-0.5.0/tests/test_tool_metadata.py +105 -0
- petfishframework-0.5.0/tests/test_tool_retry.py +98 -0
- petfishframework-0.5.0/tests/test_tool_schema.py +88 -0
- petfishframework-0.5.0/tests/test_tool_timeout.py +78 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/uv.lock +1 -1
- petfishframework-0.4.2/src/petfishframework/mcp/client.py +0 -96
- petfishframework-0.4.2/src/petfishframework/tools/__init__.py +0 -12
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.env.example +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.gitattributes +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.github/workflows/ci.yml +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.github/workflows/publish.yml +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.gitignore +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.sisyphus/plans/v0.1.6-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.sisyphus/plans/v0.2.0-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.sisyphus/plans/v0.3.0-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/.sisyphus/plans/v0.4.0-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/AGENTS.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/AGENTS.md.new +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/CONTRIBUTING.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/Dockerfile +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/LICENSE +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/SECURITY.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/conftest.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docker-compose.yml +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/architecture.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/benchmark-results.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/deployment.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/development-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/development.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/enterprise-expense-demo.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_0_1_4_playground_recommendations.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_playground_report.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_production_readiness_roadmap.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_recommendations.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_1_6_playground_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_1_7_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_1_8_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_2_1_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_2_2_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_3_0_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/archives/petfishframework_v0_4_0_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/feedbacks/petfishframework_v0_4_1_review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/release-checklist.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/release-protocol.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/competitor-analysis/README.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/competitor-analysis/competitor-matrix.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/competitor-analysis/market-brief.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/competitor-analysis/positioning-map.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/competitor-analysis/swot-analysis.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/literature-review/inclusion-exclusion-criteria.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/literature-review/literature-matrix.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/literature-review/literature-review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/literature-review/search-strategy.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/research/reference-repos-absorption.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/test-results-report.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/threat-model.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/usage-guide.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/docs/validation-roadmap.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/initialization-report.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/mcp/README.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/mcp/connection-checklist.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/mcp/mcp-config.example.json +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/opencode.json +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/qa/code-review-checklist.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/qa/qa-review.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/qa/qc-gate-decision.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/qa/test-plan.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/__main__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/config.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/agent.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/compiled.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/contracts.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/conversation.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/events.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/session.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/structured.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/core/types.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/credentials/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/credentials/broker.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/credentials/token.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/credentials/vault_adapter.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/mcp/server.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/mcp/wrapper.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/models/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/models/anthropic.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/models/fake.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/models/openai.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/observability/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/observability/otel_sink.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/observability/siem_sink.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/observability/sinks.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/conditions.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/engine.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/rule.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/test_runner.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/policies/validator.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reasoning/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reasoning/lats.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reasoning/llm_plus_p.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reasoning/react.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/audit_report.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/cost.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/cost_report.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/pass_at_k.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/replay.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/retry.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/reliability/timeout.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/retrieval/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/retrieval/adaptive.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/retrieval/crag.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/retrieval/memory_store.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/agent_tool.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/calculator.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/path_planner.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/registry.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/src/petfishframework/tools/word_sorter.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tasks/backlog.md +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/integration/__init__.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/integration/test_anthropic_integration.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/integration/test_openai_integration.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/policies/enterprise-expense.tests.yaml +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_agent_tool.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_anthropic_adapter.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_api_agent_lifecycle.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_api_edge_cases.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_api_integration.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_api_public_surface.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_api_type_safety.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_async.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_audit_report_v2.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_conversation.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_credential_broker.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_credential_integration.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_degrade.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_degrade_failclosed.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_enterprise_demo.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_m2_m3_m4.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_main_entry.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_mcp.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_openai_adapter.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_otel_sink.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_pass_at_k.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_permission_semantics.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_quickstart_smoke.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_replay.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_replay_rerun.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_replay_resume.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_retrieval.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_retry.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_siem_export.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_skeleton.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_stdio_transport.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_streaming.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_structured.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_tool_registry.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v016_semantics.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v018.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v019.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v2_interface_compatibility.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v2_lats.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_v2_llm_plus_p.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_vault_adapter.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_yaml_policy.py +0 -0
- {petfishframework-0.4.2 → petfishframework-0.5.0}/tests/test_yaml_policy_suite.py +0 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# petfishFramework v0.5.0 开发计划
|
|
2
|
+
|
|
3
|
+
> 基于 v0.4.5 状态 + production readiness roadmap + 全部 deferred 项
|
|
4
|
+
> 目标:Tool / MCP Governance — 把工具和 MCP 作为企业能力资产治理
|
|
5
|
+
> 原则:**TDD 先行,pre_release.py 门禁,文档同步作为完成条件**
|
|
6
|
+
|
|
7
|
+
## v0.5.0 使命
|
|
8
|
+
|
|
9
|
+
> 每个工具有验证过的输入、有界的执行(timeout/retry/rate)、分类的风险与默认策略。
|
|
10
|
+
> MCP server 被 allowlist 管理、health-checked、schema-pinned。
|
|
11
|
+
> 没有工具在 ungoverned 状态下执行。
|
|
12
|
+
|
|
13
|
+
## v0.4.5 基线(代码核实)
|
|
14
|
+
|
|
15
|
+
| 能力 | 状态 | 位置 |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `TimeoutPolicy` / `with_timeout` | 独立工具 — **未接入 tool calls** | `reliability/timeout.py:28` |
|
|
18
|
+
| `RetryPolicy` / `with_retry` | 独立工具 — 仅 `RetryModelAdapter` 用于 models | `reliability/retry.py:39` |
|
|
19
|
+
| `BaseTool` metadata | 字段存在但**不强制** | `tools/base.py:16` |
|
|
20
|
+
| `input_schema` | 每个工具都有 — **从未验证** | `tools/base.py:24` |
|
|
21
|
+
| `RuntimeEnvironment.call()` | 权限门 ✓ budget ✓ audit ✓ — **无 schema/timeout/retry/ratelimit** | `core/environment.py:115` |
|
|
22
|
+
| `RiskLevel` enum | LOW/MEDIUM/HIGH/CRITICAL — **纯 metadata,无默认策略** | `core/contracts.py:31` |
|
|
23
|
+
| MCP client | `connect_stdio` + `MCPToolWrapper` 可用 | `mcp/client.py:59` |
|
|
24
|
+
| `serve_as_mcp` | `NotImplementedError` stub | `mcp/server.py:7` |
|
|
25
|
+
| CredentialBroker + ScopedToken | 工作模式(max_uses, TTL) | `credentials/broker.py`, `token.py` |
|
|
26
|
+
| 测试 | 308 tests, `asyncio_mode=auto` | `pyproject.toml:55` |
|
|
27
|
+
|
|
28
|
+
## 设计决策
|
|
29
|
+
|
|
30
|
+
### D1 — Schema validation 位置与 PARTIAL_ALLOW 交互
|
|
31
|
+
|
|
32
|
+
新建 `ToolSchemaValidator` 类,接入 `RuntimeEnvironment.call()`,位于权限门之后、PARTIAL_ALLOW arg-filtering 之后、credential injection 之前。
|
|
33
|
+
|
|
34
|
+
- 验证失败 → `ToolResult(error="schema_violation: <detail>")`,工具不执行,发出 `tool.schema_violation` 事件。
|
|
35
|
+
- **无硬依赖**:内置轻量 validator 覆盖 type/required/properties/enum/additionalProperties。`jsonschema` 作为可选 extra(`pip install petfishframework[schema]`),按 OTel/Vault 模式优雅降级。
|
|
36
|
+
- PARTIAL_ALLOW 交互:验证在字段过滤**之后**运行,验证的是实际将执行的缩减参数集。
|
|
37
|
+
- **默认 opt-in(lenient)**:不破坏现有 308 测试和用户代码。
|
|
38
|
+
|
|
39
|
+
### D2 — Rate limiting 粒度与计数器位置
|
|
40
|
+
|
|
41
|
+
`RateLimitPolicy` dataclass(per-tool `max_calls` + `window_s`)+ `RateLimiter` 类,**session-scoped** 滑动窗口计数器(keyed by `(session_id, tool_name)` → deque of timestamps)。RuntimeEnvironment 可选字段。
|
|
42
|
+
|
|
43
|
+
- 超限 → `ToolResult(error="rate_limited")`,发出 `tool.rate_limited` 事件,工具不执行。
|
|
44
|
+
- Session-scoped(非全局),匹配现有 `session_id` 字段。Per-tenant → v0.6。
|
|
45
|
+
|
|
46
|
+
### D3 — Risk classification 默认行为
|
|
47
|
+
|
|
48
|
+
新建 `RiskClassificationPolicy`(implements `PermissionPolicy`)。映射 `RiskLevel` → 默认 `DecisionEffect`:
|
|
49
|
+
- CRITICAL/HIGH → REQUIRE_APPROVAL
|
|
50
|
+
- MEDIUM/LOW → ALLOW
|
|
51
|
+
|
|
52
|
+
可组合(deny-overrides)。**不改 RiskLevel enum 或现有工具。Opt-in。**
|
|
53
|
+
|
|
54
|
+
### D4 — Sandbox 隔离方案
|
|
55
|
+
|
|
56
|
+
**v0.5 不实现 sandbox execution。** 推迟到 v0.6+。
|
|
57
|
+
|
|
58
|
+
理由:subprocess 隔离在 Alpha 框架中暗示安全边界,无法充分支持。Phase A-D 交付 ~90% 治理价值且风险低。sandbox 作为独立 Phase E 可选,但默认 deferred。
|
|
59
|
+
|
|
60
|
+
### D5 — MCP 治理范围
|
|
61
|
+
|
|
62
|
+
聚焦 **MCP client governance**。MCP server mode(`serve_as_mcp`)推迟到 v0.6+。
|
|
63
|
+
|
|
64
|
+
v0.5 交付:allowlist、schema pinning、risk mapping、health check、lifecycle management。
|
|
65
|
+
|
|
66
|
+
### D6 — Commit 粒度
|
|
67
|
+
|
|
68
|
+
Per-feature commit(14 个 commit),每个独立通过 pytest + ruff。
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Phase A — Tool Schema Validation & Metadata Foundation
|
|
73
|
+
|
|
74
|
+
### A1: Tool Schema Strict Validation
|
|
75
|
+
|
|
76
|
+
**TDD tests** (`tests/test_tool_schema.py`, 5 tests):
|
|
77
|
+
```
|
|
78
|
+
test_valid_args_pass_validation — args 匹配 schema → 正常执行
|
|
79
|
+
test_missing_required_field_rejected — required 字段缺失 → schema_violation error,不执行
|
|
80
|
+
test_wrong_type_rejected — string 给 int 字段 → 拒绝
|
|
81
|
+
test_additional_properties_rejected — additionalProperties:false 时多余字段 → 拒绝
|
|
82
|
+
test_validation_after_partial_allow — PARTIAL_ALLOW 剥离字段后验证缩减集
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Implementation**:
|
|
86
|
+
- `src/petfishframework/tools/schema_validator.py` — `ToolSchemaValidator.validate(schema, args) -> list[str]`
|
|
87
|
+
- 内置 validator: type/required/properties/enum/additionalProperties;`jsonschema` 可选委托
|
|
88
|
+
- `pyproject.toml`: `schema = ["jsonschema>=4.0"]`
|
|
89
|
+
- 接入 `RuntimeEnvironment.call()` / `call_async()`,位于 PARTIAL_ALLOW filter 和 credential injection 之间
|
|
90
|
+
- 新事件: `tool.schema_violation`
|
|
91
|
+
|
|
92
|
+
**Files**: `tools/schema_validator.py` (new), `tests/test_tool_schema.py` (new), `core/environment.py` (modify), `tools/__init__.py` (modify), `pyproject.toml` (modify)
|
|
93
|
+
|
|
94
|
+
### A2: Tool Metadata Required (strict/lenient mode)
|
|
95
|
+
|
|
96
|
+
**TDD tests** (`tests/test_tool_metadata.py`, 3 tests):
|
|
97
|
+
```
|
|
98
|
+
test_tool_with_full_metadata_passes_strict — 全 metadata → OK
|
|
99
|
+
test_tool_missing_metadata_rejected_in_strict — strict + 缺 risk_level → 注册时拒绝
|
|
100
|
+
test_lenient_mode_warns_not_blocks — lenient + 缺 side_effect → warning,继续
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Implementation**:
|
|
104
|
+
- `ToolMetadataPolicy` dataclass: `mode: Literal["strict","lenient"] = "lenient"`
|
|
105
|
+
- 在 `RuntimeEnvironment` 构造时验证(非每次调用)
|
|
106
|
+
- 默认 lenient(向后兼容)
|
|
107
|
+
|
|
108
|
+
**Files**: `tools/metadata_policy.py` (new), `tests/test_tool_metadata.py` (new), `core/environment.py` (modify), `tools/__init__.py` (modify)
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Phase B — Execution Hardening
|
|
113
|
+
|
|
114
|
+
### B1: Wire TimeoutPolicy into tool calls
|
|
115
|
+
|
|
116
|
+
**TDD tests** (`tests/test_tool_timeout.py`, 3 tests):
|
|
117
|
+
```
|
|
118
|
+
test_tool_timeout_enforced — 慢工具 + timeout → OperationTimedOut → ToolResult(error)
|
|
119
|
+
test_no_timeout_default — 无 timeout policy → 正常执行
|
|
120
|
+
test_timeout_returns_error_not_raise — timeout 被捕获,返回 ToolResult,session 继续
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Implementation**:
|
|
124
|
+
- `RuntimeEnvironment.call()` 用 `with_timeout` 包装 `tool.execute(args)`
|
|
125
|
+
- 捕获 `OperationTimedOut` → `ToolResult(error="timeout after Xs")` + `tool.timeout` 事件
|
|
126
|
+
- `call_async()` 用 `asyncio.wait_for`
|
|
127
|
+
- `RuntimeEnvironment` 新字段: `timeout_policy: TimeoutPolicy | None = None`
|
|
128
|
+
|
|
129
|
+
**Files**: `core/environment.py` (modify), `tests/test_tool_timeout.py` (new)
|
|
130
|
+
|
|
131
|
+
### B2: Wire RetryPolicy into tool calls
|
|
132
|
+
|
|
133
|
+
**TDD tests** (`tests/test_tool_retry.py`, 3 tests):
|
|
134
|
+
```
|
|
135
|
+
test_tool_retry_succeeds_on_retry — flaky tool 失败一次后成功 → retry,返回值
|
|
136
|
+
test_tool_no_retry_by_default — retry_policy=None → 不重试
|
|
137
|
+
test_tool_retry_exhausted — 持续失败 + max_retries → RetryableError → ToolResult(error)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Implementation**:
|
|
141
|
+
- 可选 `retry_policy: RetryPolicy | None` per-tool(`BaseTool.retry_policy` 字段)或 env 级别
|
|
142
|
+
- **硬门控**: 仅当 `tool.idempotent == True` 时才重试(非幂等工具重试会导致副作用重复)
|
|
143
|
+
- 用 `with_retry` 包装 `tool.execute`
|
|
144
|
+
|
|
145
|
+
**Files**: `core/environment.py` (modify), `tools/base.py` (modify), `tests/test_tool_retry.py` (new)
|
|
146
|
+
|
|
147
|
+
### B3: Idempotency Key Support
|
|
148
|
+
|
|
149
|
+
**TDD tests** (`tests/test_tool_idempotency.py`, 3 tests):
|
|
150
|
+
```
|
|
151
|
+
test_same_idempotency_key_returns_cached — 相同 key → 缓存结果,不重复执行
|
|
152
|
+
test_different_idempotency_key_executes — 不同 key → 再次执行
|
|
153
|
+
test_idempotent_tool_without_key_executes_each — 无 key → 正常执行(不 dedup)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Implementation**:
|
|
157
|
+
- `IdempotencyStore`: `dict[idempotency_key, ToolResult]` + TTL,session-scoped
|
|
158
|
+
- 执行前检查 `args.get("_idempotency_key")`,命中缓存则返回,发出 `tool.idempotent_cache_hit`
|
|
159
|
+
- `BaseTool` 新字段: `supports_idempotency_key: bool = False`
|
|
160
|
+
|
|
161
|
+
**Files**: `tools/idempotency.py` (new), `tests/test_tool_idempotency.py` (new), `core/environment.py` (modify), `tools/base.py` (modify)
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Phase C — Rate Limiting & Risk Classification
|
|
166
|
+
|
|
167
|
+
### C1: RateLimiter
|
|
168
|
+
|
|
169
|
+
**TDD tests** (`tests/test_rate_limiter.py`, 4 tests):
|
|
170
|
+
```
|
|
171
|
+
test_under_limit_executes — 3/5 → 全部执行
|
|
172
|
+
test_at_limit_executes — 5/5 → 全部执行(边界)
|
|
173
|
+
test_over_limit_blocked — 第6次在窗口内 → rate_limited error,不执行
|
|
174
|
+
test_window_reset_allows_again — window_s 过后 → 计数器重置,调用成功
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Implementation**:
|
|
178
|
+
- `tools/rate_limiter.py` — `RateLimitPolicy` (frozen dataclass) + `RateLimiter` (sliding window via `collections.deque`)
|
|
179
|
+
- `RuntimeEnvironment` 字段: `rate_limiter: RateLimiter | None = None`
|
|
180
|
+
- Per-tool 限制 via `BaseTool.rate_limit: RateLimitPolicy | None`
|
|
181
|
+
- 发出 `tool.rate_limited` 事件
|
|
182
|
+
|
|
183
|
+
**Files**: `tools/rate_limiter.py` (new), `tests/test_rate_limiter.py` (new), `core/environment.py` (modify), `tools/base.py` (modify), `tools/__init__.py` (modify)
|
|
184
|
+
|
|
185
|
+
### C2: Risk Classification Policy
|
|
186
|
+
|
|
187
|
+
**TDD tests** (`tests/test_risk_classification.py`, 3 tests):
|
|
188
|
+
```
|
|
189
|
+
test_high_risk_defaults_to_require_approval — HIGH tool + 无显式规则 → REQUIRE_APPROVAL
|
|
190
|
+
test_explicit_allow_overrides_default — YamlPolicy ALLOW 规则对 HIGH tool 生效
|
|
191
|
+
test_compose_with_yaml_deny_overrides — risk policy ALLOW + yaml DENY → DENY
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Implementation**:
|
|
195
|
+
- `permissions/risk_policy.py` — `RiskClassificationPolicy(PermissionPolicy)`
|
|
196
|
+
- 可配置映射: `defaults: dict[RiskLevel, DecisionEffect]`
|
|
197
|
+
- 可组合: deny-overrides via `CompositePolicy` wrapper
|
|
198
|
+
|
|
199
|
+
**Files**: `permissions/risk_policy.py` (new), `tests/test_risk_classification.py` (new), `permissions/__init__.py` (modify)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Phase D — MCP Client Governance
|
|
204
|
+
|
|
205
|
+
### D1: MCP Server Allowlist
|
|
206
|
+
|
|
207
|
+
**TDD tests** (`tests/test_mcp_allowlist.py`, 3 tests):
|
|
208
|
+
```
|
|
209
|
+
test_allowed_server_connects — allowlist 中的 server → 连接成功
|
|
210
|
+
test_blocked_server_rejected — 不在 allowlist → ConnectionRefused
|
|
211
|
+
test_empty_allowlist_denies_all — 空 allowlist + strict → 全部拒绝
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Files**: `mcp/allowlist.py` (new), `tests/test_mcp_allowlist.py` (new), `mcp/client.py` (modify), `mcp/__init__.py` (modify)
|
|
215
|
+
|
|
216
|
+
### D2: MCP Tool Schema Pinning *(depends on A1)*
|
|
217
|
+
|
|
218
|
+
**TDD tests** (`tests/test_mcp_schema_pin.py`, 3 tests):
|
|
219
|
+
```
|
|
220
|
+
test_pin_freezes_schema — pin 发现的 schemas → 快照存储
|
|
221
|
+
test_drift_detected_on_change — server 改变 schema → drift 报告
|
|
222
|
+
test_repin_updates_snapshot — 显式 repin → 新快照替换旧
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Files**: `mcp/schema_pin.py` (new), `tests/test_mcp_schema_pin.py` (new), `mcp/client.py` (modify), `mcp/__init__.py` (modify)
|
|
226
|
+
|
|
227
|
+
### D3: MCP Tool Risk Mapping
|
|
228
|
+
|
|
229
|
+
**TDD tests** (`tests/test_mcp_risk_mapping.py`, 2 tests):
|
|
230
|
+
```
|
|
231
|
+
test_auto_classify_by_capabilities — MCP tool 有 "fs:write" → HIGH risk
|
|
232
|
+
test_custom_mapping_overrides — 显式 risk map → 覆盖自动分类
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Files**: `mcp/risk_mapper.py` (new), `tests/test_mcp_risk_mapping.py` (new), `mcp/client.py` (modify), `mcp/wrapper.py` (modify)
|
|
236
|
+
|
|
237
|
+
### D4: MCP Server Health Check + Lifecycle
|
|
238
|
+
|
|
239
|
+
**TDD tests** (`tests/test_mcp_lifecycle.py`, 4 tests):
|
|
240
|
+
```
|
|
241
|
+
test_health_check_ok — 活 server → health() 返回 True
|
|
242
|
+
test_health_check_fail — 死 server → health() 返回 False
|
|
243
|
+
test_disconnect_terminates_proc — close() → subprocess 终止,无 zombie
|
|
244
|
+
test_reconnect_after_drop — server drop → reconnect() 重建连接
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Files**: `tests/test_mcp_lifecycle.py` (new), `mcp/client.py` (modify), `mcp/stdio_transport.py` (modify), `mcp/__init__.py` (modify)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Phase E — Sandbox Execution (DEFERRED to v0.6+)
|
|
252
|
+
|
|
253
|
+
v0.5 不实现 sandbox。理由见设计决策 D4。
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 依赖图与并行化
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
Wave 1 (完全独立,可并行):
|
|
261
|
+
A1 (schema) A2 (metadata) B1 (timeout) B2 (retry) B3 (idempotency)
|
|
262
|
+
C1 (rate) C2 (risk)
|
|
263
|
+
|
|
264
|
+
Wave 2 (依赖 Wave 1):
|
|
265
|
+
D2 (schema pin) ───── depends on A1
|
|
266
|
+
|
|
267
|
+
Wave 3 (MCP governance cluster):
|
|
268
|
+
D1 (allowlist) D3 (risk mapping) D4 (health/lifecycle)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Wave 1 的 7 个 feature 完全独立 — 可并行 7 个 sub-agent。
|
|
272
|
+
Wave 2 的 1 个 feature 可在 Wave 1 后并行。
|
|
273
|
+
Wave 3 的 3 个 feature 可在 Wave 2 后并行。
|
|
274
|
+
|
|
275
|
+
## 测试预估
|
|
276
|
+
|
|
277
|
+
| Phase | Feature | 新测试 |
|
|
278
|
+
|---|---|---|
|
|
279
|
+
| A | A1 schema validation | 5 |
|
|
280
|
+
| A | A2 metadata policy | 3 |
|
|
281
|
+
| B | B1 timeout wiring | 3 |
|
|
282
|
+
| B | B2 retry wiring | 3 |
|
|
283
|
+
| B | B3 idempotency | 3 |
|
|
284
|
+
| C | C1 rate limit | 4 |
|
|
285
|
+
| C | C2 risk classification | 3 |
|
|
286
|
+
| D | D1 MCP allowlist | 3 |
|
|
287
|
+
| D | D2 schema pinning | 3 |
|
|
288
|
+
| D | D3 risk mapping | 2 |
|
|
289
|
+
| D | D4 health/lifecycle | 4 |
|
|
290
|
+
| **Total** | | **~36 new tests** |
|
|
291
|
+
|
|
292
|
+
**预计: 308 → ~344 tests。** 现有 308 必须保持 green。
|
|
293
|
+
|
|
294
|
+
## Scope 边界
|
|
295
|
+
|
|
296
|
+
### IN scope (v0.5.0)
|
|
297
|
+
- Tool schema strict validation(内置 + 可选 jsonschema)
|
|
298
|
+
- Tool metadata strict/lenient enforcement
|
|
299
|
+
- TimeoutPolicy + RetryPolicy 接入 tool 执行路径
|
|
300
|
+
- Idempotency key deduplication
|
|
301
|
+
- Per-tool, session-scoped rate limiting
|
|
302
|
+
- RiskLevel → DecisionEffect default policy
|
|
303
|
+
- MCP server allowlist
|
|
304
|
+
- MCP tool schema pinning + drift detection
|
|
305
|
+
- MCP tool risk auto-mapping
|
|
306
|
+
- MCP health check + lifecycle(connect/disconnect/reconnect)
|
|
307
|
+
|
|
308
|
+
### OUT of scope (deferred to v0.6+)
|
|
309
|
+
- ❌ MCP server mode(`serve_as_mcp` 保持 stub)
|
|
310
|
+
- ❌ Sandbox execution(subprocess/container isolation)
|
|
311
|
+
- ❌ Per-tenant / per-user rate limiting
|
|
312
|
+
- ❌ Tool rollback / compensation
|
|
313
|
+
- ❌ MCP transport security(TLS, auth tokens)
|
|
314
|
+
- ❌ Prompt injection defense for MCP tool descriptions
|
|
315
|
+
- ❌ Policy hot-reload
|
|
316
|
+
- ❌ Multi-tenant policy namespaces
|
|
317
|
+
|
|
318
|
+
## 风险评估
|
|
319
|
+
|
|
320
|
+
| Phase | 风险 | 缓解 |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| A1 | 内置 validator 与 jsonschema 边缘差异 | 提供 jsonschema extra;文档覆盖范围;两条路径集成测试 |
|
|
323
|
+
| B1 | `with_timeout` 用 ThreadPoolExecutor,无法中断 CPU-bound 工具 | 文档限制;async 路径用 asyncio.wait_for(真正取消) |
|
|
324
|
+
| B2 | 重试非幂等工具导致副作用重复 | **硬门控**: 仅 `tool.idempotent == True` 时重试。显式测试。 |
|
|
325
|
+
| C1 | 滑动窗口在分布式环境有时钟偏移 | v0.5 单进程;文档限制 |
|
|
326
|
+
| D2 | Schema drift 因无害 description 变化误报 | 仅 pin `input_schema`(结构),不含 description |
|
|
327
|
+
| D4 | Windows 上 subprocess zombie | `atexit` + context manager;跨平台测试 |
|
|
@@ -2,6 +2,77 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to petfishFramework will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.5.0] — 2026-07-08
|
|
6
|
+
|
|
7
|
+
### Tool / MCP Governance
|
|
8
|
+
|
|
9
|
+
#### Phase A: Tool Schema & Metadata
|
|
10
|
+
- **ToolSchemaValidator** — JSON schema validation on tool args before execution. Built-in validator covers type/required/properties/enum/additionalProperties. Optional `jsonschema` extra for full draft-2020 compliance. Wired into `RuntimeEnvironment.call()` after PARTIAL_ALLOW filter.
|
|
11
|
+
- **ToolMetadataPolicy** — strict/lenient enforcement of tool metadata fields (risk_level, side_effect, idempotent, etc.). Validation at RuntimeEnvironment construction time. Default lenient (backward compatible).
|
|
12
|
+
|
|
13
|
+
#### Phase B: Execution Hardening
|
|
14
|
+
- **TimeoutPolicy wiring** — `with_timeout` wraps `tool.execute()` in `call()`. Timeout caught internally, returns `ToolResult(error="timeout")`, never raises to caller. Async path uses `asyncio.wait_for`.
|
|
15
|
+
- **RetryPolicy wiring** — `with_retry` wraps idempotent tool execution. **Hard gate: only retries when `tool.idempotent == True`** (non-idempotent tools never retried — prevents duplicate side effects).
|
|
16
|
+
- **IdempotencyStore** — session-scoped dedup via `_idempotency_key` in args. TTL-based cache. Cache hit returns early without executing tool.
|
|
17
|
+
|
|
18
|
+
#### Phase C: Rate Limiting & Risk Classification
|
|
19
|
+
- **RateLimiter** — per-tool, session-scoped sliding-window rate limiting. `RateLimitPolicy(max_calls, window_s)` configurable per-tool via `BaseTool.rate_limit` or env-level. Over-limit → `ToolResult(error="rate_limited")`.
|
|
20
|
+
- **RiskClassificationPolicy** — maps `RiskLevel` → default `DecisionEffect` (CRITICAL/HIGH → REQUIRE_APPROVAL, MEDIUM/LOW → ALLOW). Opt-in via `permission_policy=`. **CompositePolicy** combines multiple policies with deny-overrides semantics.
|
|
21
|
+
|
|
22
|
+
#### Phase D: MCP Client Governance
|
|
23
|
+
- **MCPAllowlist** — governs which MCP servers can connect. Strict mode rejects unlisted servers before subprocess spawn. Lenient default (backward compatible).
|
|
24
|
+
- **SchemaPin** — freezes discovered MCP tool `input_schema` hashes for drift detection. Description-only changes do NOT trigger drift (structural pinning only). `MCPClient.pin_schemas()` + `verify_schemas()`.
|
|
25
|
+
- **MCPRiskMapper** — auto-classifies MCP tools by capability → RiskLevel (write/exec/network → HIGH, read → LOW). Applied during `discover_tools()`.
|
|
26
|
+
- **Health check + lifecycle** — `MCPClient.health()`, `close()`, `reconnect()`, context manager (`__enter__`/`__exit__`). No zombie subprocesses.
|
|
27
|
+
|
|
28
|
+
#### New BaseTool Fields (all optional, backward compatible)
|
|
29
|
+
- `rate_limit: RateLimitPolicy | None = None`
|
|
30
|
+
- `retry_policy: RetryPolicy | None = None`
|
|
31
|
+
- `supports_idempotency_key: bool = False`
|
|
32
|
+
|
|
33
|
+
#### New RuntimeEnvironment Fields (all optional, None = no-op)
|
|
34
|
+
- `timeout_policy: TimeoutPolicy | None = None`
|
|
35
|
+
- `rate_limiter: RateLimiter | None = None`
|
|
36
|
+
- `idempotency_store: IdempotencyStore | None = None`
|
|
37
|
+
- `schema_validator: ToolSchemaValidator | None = None`
|
|
38
|
+
|
|
39
|
+
#### Test Growth
|
|
40
|
+
- v0.4.5: 308 tests → v0.5.0: 352 tests (+44)
|
|
41
|
+
- All existing tests unmodified (backward compatible)
|
|
42
|
+
|
|
43
|
+
#### Deferred to v0.6+
|
|
44
|
+
- ❌ MCP server mode (`serve_as_mcp`)
|
|
45
|
+
- ❌ Sandbox execution (subprocess/container isolation)
|
|
46
|
+
- ❌ Per-tenant rate limiting
|
|
47
|
+
- ❌ Policy hot-reload
|
|
48
|
+
|
|
49
|
+
## [0.4.5] — 2026-07-08
|
|
50
|
+
|
|
51
|
+
### v0.5 Readiness: API Documentation + Technical Debt Cleanup
|
|
52
|
+
|
|
53
|
+
#### API Reference Overhaul (28 APIs documented)
|
|
54
|
+
- `docs/api.md` expanded from 1471 to 2203 lines (+50%)
|
|
55
|
+
- All 28 previously-undocumented public APIs now have full signatures, parameters, and examples:
|
|
56
|
+
- **Observability**: OTelSink, SIEMSink (with redact_keys boundary note)
|
|
57
|
+
- **Reliability**: RetryPolicy, with_retry, with_retry_async, RetryableError, RetryModelAdapter, retry_model_adapter, TimeoutPolicy, with_timeout, OperationTimedOut, RerunEnvironment, RerunResult, CostReport
|
|
58
|
+
- **Configuration**: FrameworkConfig (from_env, from_dict)
|
|
59
|
+
- **Conversation Memory**: ConversationStore, InMemoryConversationStore
|
|
60
|
+
- **Structured Output**: StructuredResult, parse_json, parse_structured
|
|
61
|
+
- **Tools**: AgentAsTool, WordSorter
|
|
62
|
+
- **Models**: AnthropicModel, AsyncFakeModel
|
|
63
|
+
- **Policies**: PolicyRule, load_policy
|
|
64
|
+
- **MCP**: serve_as_mcp (marked as v0.5 stub)
|
|
65
|
+
|
|
66
|
+
#### API Stability Policy
|
|
67
|
+
- New `docs/api-stability.md` classifies all public APIs into Stable / Experimental / Internal tiers
|
|
68
|
+
- Documents deprecation process and v1.0 freeze criteria
|
|
69
|
+
|
|
70
|
+
#### Code Cleanup (stale markers removed)
|
|
71
|
+
- `permissions/__init__.py`: docstring updated — CredentialBroker is implemented, not TODO
|
|
72
|
+
- `permissions/model.py`: DefaultAllowPolicy comment clarified (allow-all by design, not a skeleton TODO)
|
|
73
|
+
- `core/environment.py`: DEGRADE docstring fixed — tool switching IS implemented (was incorrectly marked "future work"); visibility gate clarified as v0.5 planned
|
|
74
|
+
- `docs/skeleton-completeness-checklist.md`: comprehensively updated to reflect v0.4.5 state (RESUME/RERUN, Pass^k, CredentialBroker, OTel/SIEM, retry/timeout all marked ✅)
|
|
75
|
+
|
|
5
76
|
## [0.4.2] — 2026-07-08
|
|
6
77
|
|
|
7
78
|
### CI & Deployment Hardening
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: petfishframework
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: A lightweight runtime framework for reliable, auditable, budget-aware, and permission-aware AI agents.
|
|
5
5
|
Project-URL: Homepage, https://github.com/kylecui/petfishFramework
|
|
6
6
|
Project-URL: Documentation, https://github.com/kylecui/petfishFramework/tree/master/docs
|
|
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
|
|
|
39
39
|
|
|
40
40
|
[](https://www.python.org/downloads/)
|
|
41
41
|
[](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
|
|
42
|
-
[](https://github.com/kylecui/petfishFramework/tree/master/tests/)
|
|
43
43
|
|
|
44
44
|
**Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
|
|
45
45
|
|
|
@@ -275,7 +275,7 @@ result = session.run()
|
|
|
275
275
|
|
|
276
276
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
277
277
|
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
278
|
-
- **v0.
|
|
278
|
+
- **v0.5.x** (current): Tool/MCP governance — schema validation, rate limiting, risk classification, retry/timeout wiring, MCP allowlist/schema-pin/risk-map/lifecycledes, Vault adapter, Docker, threat model ✅
|
|
279
279
|
|
|
280
280
|
## Current Limitations
|
|
281
281
|
|
|
@@ -306,7 +306,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
306
306
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
307
307
|
cd petfishFramework
|
|
308
308
|
uv sync --all-extras
|
|
309
|
-
uv run pytest #
|
|
309
|
+
uv run pytest # 352 tests
|
|
310
310
|
uv run ruff check src/ tests/
|
|
311
311
|
```
|
|
312
312
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
6
|
[](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
|
|
7
|
-
[](https://github.com/kylecui/petfishFramework/tree/master/tests/)
|
|
8
8
|
|
|
9
9
|
**Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
|
|
10
10
|
|
|
@@ -240,7 +240,7 @@ result = session.run()
|
|
|
240
240
|
|
|
241
241
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
242
242
|
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
243
|
-
- **v0.
|
|
243
|
+
- **v0.5.x** (current): Tool/MCP governance — schema validation, rate limiting, risk classification, retry/timeout wiring, MCP allowlist/schema-pin/risk-map/lifecycledes, Vault adapter, Docker, threat model ✅
|
|
244
244
|
|
|
245
245
|
## Current Limitations
|
|
246
246
|
|
|
@@ -271,7 +271,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
271
271
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
272
272
|
cd petfishFramework
|
|
273
273
|
uv sync --all-extras
|
|
274
|
-
uv run pytest #
|
|
274
|
+
uv run pytest # 352 tests
|
|
275
275
|
uv run ruff check src/ tests/
|
|
276
276
|
```
|
|
277
277
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# API Stability Policy
|
|
2
|
+
|
|
3
|
+
> Effective: v0.4.5
|
|
4
|
+
> Goal: Help users understand which APIs are safe to depend on before v1.0.
|
|
5
|
+
|
|
6
|
+
## Stability Tiers
|
|
7
|
+
|
|
8
|
+
| Tier | Meaning | Breaking changes | Versioning |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| **Stable** | API signature and semantics will not change before v1.0 without a deprecation cycle (min 1 minor version). | Only for security fixes. | Patch (0.4.x) |
|
|
11
|
+
| **Experimental** | API exists and works, but may change signature or semantics in the next minor version. | Allowed with CHANGELOG note. | Minor (0.x.0) |
|
|
12
|
+
| **Internal** | Used by the framework internally. May change or be removed without notice. | No guarantees. | Any |
|
|
13
|
+
|
|
14
|
+
## Classification
|
|
15
|
+
|
|
16
|
+
### Stable
|
|
17
|
+
|
|
18
|
+
These APIs have been validated by 300+ tests and are used in production-facing examples:
|
|
19
|
+
|
|
20
|
+
- `Agent`, `Session` — core execution abstractions
|
|
21
|
+
- `Budget`, `BudgetExceeded` — budget enforcement
|
|
22
|
+
- `DecisionEffect` (all 6 values) — permission semantics
|
|
23
|
+
- `Subject`, `Action`, `Resource`, `AccessContext`, `Decision` — SARC model
|
|
24
|
+
- `PermissionPolicy` protocol — policy interface
|
|
25
|
+
- `DefaultAllowPolicy`, `DenyByDefaultPolicy` — built-in policies
|
|
26
|
+
- `Event`, `EventEmitter` — event infrastructure
|
|
27
|
+
- `Result`, `Task`, `Step`, `Trajectory`, `Usage` — core types
|
|
28
|
+
- `Tool` protocol, `BaseTool`, `@tool` decorator
|
|
29
|
+
- `Calculator`, `WordSorter` — reference tools
|
|
30
|
+
- `FakeModel` — testing model
|
|
31
|
+
- `ReAct` — default reasoning strategy
|
|
32
|
+
- `RuntimeEnvironment` — the chokepoint
|
|
33
|
+
- `AuditReport`, `audit_report_from_session` — audit output
|
|
34
|
+
- `CredentialBroker`, `ScopedToken` — credential governance
|
|
35
|
+
- `YamlPolicy`, `PolicyRule` — YAML policy engine
|
|
36
|
+
- `pass_at_k`, `pass_at_k_with_perturbations` — reliability metric
|
|
37
|
+
|
|
38
|
+
### Experimental
|
|
39
|
+
|
|
40
|
+
These APIs work and are tested, but their signatures or semantics may change:
|
|
41
|
+
|
|
42
|
+
- `OTelSink`, `SIEMSink` — observability sinks (redaction API may evolve)
|
|
43
|
+
- `RecordingEnvironment`, `ReplayEnvironment`, `RerunEnvironment`, `ResumableEnvironment` — replay wrappers
|
|
44
|
+
- `RerunResult` — divergence detection output format may change
|
|
45
|
+
- `RetryPolicy`, `with_retry`, `RetryModelAdapter` — retry infrastructure
|
|
46
|
+
- `TimeoutPolicy`, `with_timeout` — timeout infrastructure
|
|
47
|
+
- `VaultCredentialSource` — Vault adapter (needs real-world validation)
|
|
48
|
+
- `OpenAIModel`, `AnthropicModel` — model adapters (provider API changes)
|
|
49
|
+
- `LATS`, `LLMPlusP` — reasoning strategies (lightweight implementations)
|
|
50
|
+
- `CRAGRetriever`, `AdaptiveRetriever`, `MemoryRetriever` — retrieval (lightweight)
|
|
51
|
+
- `AgentAsTool` — multi-agent delegation
|
|
52
|
+
- `ConversationStore`, `InMemoryConversationStore` — conversation memory
|
|
53
|
+
- `StructuredResult`, `parse_json`, `parse_structured` — structured output
|
|
54
|
+
- `FrameworkConfig` — configuration system
|
|
55
|
+
- `CostReport` — cost reporting format
|
|
56
|
+
- `connect_stdio`, `MCPClient` — MCP client
|
|
57
|
+
- Policy condition matchers — YAML matcher set may expand/change
|
|
58
|
+
- `SIEMSink.redact_keys` — redaction key set may change defaults
|
|
59
|
+
|
|
60
|
+
### Internal
|
|
61
|
+
|
|
62
|
+
These are implementation details that should not be directly imported:
|
|
63
|
+
|
|
64
|
+
- `CostAccountant` — internal cost tracking (use `Result.usage` instead)
|
|
65
|
+
- `CapabilityProjection` — visibility gate (not yet enforced)
|
|
66
|
+
- `CapabilityGrant` — audit artifact type (not yet emitted)
|
|
67
|
+
- `CompiledContext`, `TaskSpec`, `MemorySlice`, `EvidenceBundle`, `OutputContract` — compiled context types
|
|
68
|
+
- `MemoryView` — memory protocol (empty stub)
|
|
69
|
+
- `serve_as_mcp` — MCP server stub (raises NotImplementedError)
|
|
70
|
+
- `pass_at_k` perturbation functions (`canonical`, `order_shuffled`, etc.) — stable interface but internal implementations
|
|
71
|
+
|
|
72
|
+
## Deprecation Process
|
|
73
|
+
|
|
74
|
+
When an API moves from Stable to deprecated:
|
|
75
|
+
|
|
76
|
+
1. Add `DeprecationWarning` in the next minor version
|
|
77
|
+
2. Document replacement in CHANGELOG
|
|
78
|
+
3. Keep the API functional for at least 1 minor version
|
|
79
|
+
4. Remove in the following minor version (or v1.0 if major)
|
|
80
|
+
|
|
81
|
+
## v1.0 Freeze Criteria
|
|
82
|
+
|
|
83
|
+
Before declaring v1.0:
|
|
84
|
+
|
|
85
|
+
- All Stable APIs have been unchanged for 2+ minor versions
|
|
86
|
+
- All Experimental APIs are reclassified as Stable or explicitly dropped
|
|
87
|
+
- Breaking changes require semver-major version bump
|
|
88
|
+
- Migration guide published for any dropped APIs
|