petfishframework 0.2.1__tar.gz → 0.2.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.
Files changed (138) hide show
  1. {petfishframework-0.2.1 → petfishframework-0.2.2}/PKG-INFO +5 -3
  2. {petfishframework-0.2.1 → petfishframework-0.2.2}/README.md +4 -2
  3. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/api.md +2 -2
  4. petfishframework-0.2.2/docs/enterprise-expense-demo.md +92 -0
  5. petfishframework-0.2.2/docs/feedbacks/petfishframework_v0_2_1_review.md +687 -0
  6. {petfishframework-0.2.1 → petfishframework-0.2.2}/pyproject.toml +1 -1
  7. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/__init__.py +1 -1
  8. {petfishframework-0.2.1 → petfishframework-0.2.2}/uv.lock +1 -1
  9. {petfishframework-0.2.1 → petfishframework-0.2.2}/.env.example +0 -0
  10. {petfishframework-0.2.1 → petfishframework-0.2.2}/.github/workflows/ci.yml +0 -0
  11. {petfishframework-0.2.1 → petfishframework-0.2.2}/.gitignore +0 -0
  12. {petfishframework-0.2.1 → petfishframework-0.2.2}/.sisyphus/plans/v0.1.6-plan.md +0 -0
  13. {petfishframework-0.2.1 → petfishframework-0.2.2}/.sisyphus/plans/v0.2.0-plan.md +0 -0
  14. {petfishframework-0.2.1 → petfishframework-0.2.2}/AGENTS.md +0 -0
  15. {petfishframework-0.2.1 → petfishframework-0.2.2}/AGENTS.md.new +0 -0
  16. {petfishframework-0.2.1 → petfishframework-0.2.2}/CHANGELOG.md +0 -0
  17. {petfishframework-0.2.1 → petfishframework-0.2.2}/CONTRIBUTING.md +0 -0
  18. {petfishframework-0.2.1 → petfishframework-0.2.2}/LICENSE +0 -0
  19. {petfishframework-0.2.1 → petfishframework-0.2.2}/SECURITY.md +0 -0
  20. {petfishframework-0.2.1 → petfishframework-0.2.2}/conftest.py +0 -0
  21. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/architecture.md +0 -0
  22. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/benchmark-results.md +0 -0
  23. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/development-plan.md +0 -0
  24. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/development.md +0 -0
  25. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_0_1_4_playground_recommendations.md +0 -0
  26. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_playground_report.md +0 -0
  27. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_production_readiness_roadmap.md +0 -0
  28. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_recommendations.md +0 -0
  29. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_v0_1_6_playground_review.md +0 -0
  30. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_v0_1_7_review.md +0 -0
  31. {petfishframework-0.2.1/docs/feedbacks → petfishframework-0.2.2/docs/feedbacks/archives}/petfishframework_v0_1_8_review.md +0 -0
  32. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/competitor-analysis/README.md +0 -0
  33. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/competitor-analysis/competitor-matrix.md +0 -0
  34. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/competitor-analysis/market-brief.md +0 -0
  35. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/competitor-analysis/positioning-map.md +0 -0
  36. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/competitor-analysis/swot-analysis.md +0 -0
  37. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/literature-review/inclusion-exclusion-criteria.md +0 -0
  38. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/literature-review/literature-matrix.md +0 -0
  39. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/literature-review/literature-review.md +0 -0
  40. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/literature-review/search-strategy.md +0 -0
  41. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/research/reference-repos-absorption.md +0 -0
  42. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/skeleton-completeness-checklist.md +0 -0
  43. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/test-results-report.md +0 -0
  44. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/usage-guide.md +0 -0
  45. {petfishframework-0.2.1 → petfishframework-0.2.2}/docs/validation-roadmap.md +0 -0
  46. {petfishframework-0.2.1 → petfishframework-0.2.2}/initialization-report.md +0 -0
  47. {petfishframework-0.2.1 → petfishframework-0.2.2}/mcp/README.md +0 -0
  48. {petfishframework-0.2.1 → petfishframework-0.2.2}/mcp/connection-checklist.md +0 -0
  49. {petfishframework-0.2.1 → petfishframework-0.2.2}/mcp/mcp-config.example.json +0 -0
  50. {petfishframework-0.2.1 → petfishframework-0.2.2}/opencode.json +0 -0
  51. {petfishframework-0.2.1 → petfishframework-0.2.2}/qa/code-review-checklist.md +0 -0
  52. {petfishframework-0.2.1 → petfishframework-0.2.2}/qa/qa-review.md +0 -0
  53. {petfishframework-0.2.1 → petfishframework-0.2.2}/qa/qc-gate-decision.md +0 -0
  54. {petfishframework-0.2.1 → petfishframework-0.2.2}/qa/test-plan.md +0 -0
  55. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/config.py +0 -0
  56. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/__init__.py +0 -0
  57. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/agent.py +0 -0
  58. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/compiled.py +0 -0
  59. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/contracts.py +0 -0
  60. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/conversation.py +0 -0
  61. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/environment.py +0 -0
  62. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/events.py +0 -0
  63. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/session.py +0 -0
  64. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/structured.py +0 -0
  65. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/core/types.py +0 -0
  66. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/mcp/__init__.py +0 -0
  67. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/mcp/client.py +0 -0
  68. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/mcp/server.py +0 -0
  69. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/mcp/stdio_transport.py +0 -0
  70. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/mcp/wrapper.py +0 -0
  71. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/models/__init__.py +0 -0
  72. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/models/anthropic.py +0 -0
  73. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/models/fake.py +0 -0
  74. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/models/openai.py +0 -0
  75. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/observability/__init__.py +0 -0
  76. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/observability/sinks.py +0 -0
  77. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/permissions/__init__.py +0 -0
  78. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/permissions/model.py +0 -0
  79. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reasoning/__init__.py +0 -0
  80. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reasoning/lats.py +0 -0
  81. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reasoning/llm_plus_p.py +0 -0
  82. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reasoning/react.py +0 -0
  83. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/__init__.py +0 -0
  84. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/audit_report.py +0 -0
  85. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/cost.py +0 -0
  86. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/cost_report.py +0 -0
  87. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/pass_at_k.py +0 -0
  88. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/replay.py +0 -0
  89. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/retry.py +0 -0
  90. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/reliability/timeout.py +0 -0
  91. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/retrieval/__init__.py +0 -0
  92. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/retrieval/adaptive.py +0 -0
  93. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/retrieval/crag.py +0 -0
  94. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/retrieval/memory_store.py +0 -0
  95. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/__init__.py +0 -0
  96. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/agent_tool.py +0 -0
  97. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/base.py +0 -0
  98. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/calculator.py +0 -0
  99. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/path_planner.py +0 -0
  100. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/registry.py +0 -0
  101. {petfishframework-0.2.1 → petfishframework-0.2.2}/src/petfishframework/tools/word_sorter.py +0 -0
  102. {petfishframework-0.2.1 → petfishframework-0.2.2}/tasks/backlog.md +0 -0
  103. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/integration/__init__.py +0 -0
  104. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/integration/test_anthropic_integration.py +0 -0
  105. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/integration/test_openai_integration.py +0 -0
  106. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_agent_tool.py +0 -0
  107. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_anthropic_adapter.py +0 -0
  108. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_api_agent_lifecycle.py +0 -0
  109. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_api_edge_cases.py +0 -0
  110. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_api_integration.py +0 -0
  111. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_api_public_surface.py +0 -0
  112. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_api_type_safety.py +0 -0
  113. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_async.py +0 -0
  114. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_audit_report_v2.py +0 -0
  115. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_conversation.py +0 -0
  116. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_degrade.py +0 -0
  117. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_degrade_failclosed.py +0 -0
  118. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_enterprise_demo.py +0 -0
  119. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_m2_m3_m4.py +0 -0
  120. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_mcp.py +0 -0
  121. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_openai_adapter.py +0 -0
  122. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_pass_at_k.py +0 -0
  123. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_permission_semantics.py +0 -0
  124. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_quickstart_smoke.py +0 -0
  125. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_replay.py +0 -0
  126. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_retrieval.py +0 -0
  127. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_retry.py +0 -0
  128. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_skeleton.py +0 -0
  129. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_stdio_transport.py +0 -0
  130. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_streaming.py +0 -0
  131. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_structured.py +0 -0
  132. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_tool_registry.py +0 -0
  133. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v016_semantics.py +0 -0
  134. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v018.py +0 -0
  135. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v019.py +0 -0
  136. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v2_interface_compatibility.py +0 -0
  137. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v2_lats.py +0 -0
  138. {petfishframework-0.2.1 → petfishframework-0.2.2}/tests/test_v2_llm_plus_p.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: petfishframework
3
- Version: 0.2.1
3
+ Version: 0.2.2
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
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
33
33
 
34
34
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
35
35
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
36
- [![Tests: 234](https://img.shields.io/badge/tests-213-brightgreen.svg)](https://github.com/kylecui/petfishFramework/tree/master/tests/)
36
+ [![Tests: 234](https://img.shields.io/badge/tests-234-brightgreen.svg)](https://github.com/kylecui/petfishFramework/tree/master/tests/)
37
37
 
38
38
  **Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
39
39
 
@@ -210,7 +210,9 @@ print(result.summary())
210
210
 
211
211
  ## Enterprise PoC
212
212
 
213
- See `examples/05_enterprise_expense.py` (coming in v0.2.0 release) and `tests/test_enterprise_demo.py` for a complete enterprise expense approval scenario demonstrating all 6 DecisionEffects.
213
+ See `examples/05_enterprise_expense.py` and `tests/test_enterprise_demo.py` for a complete enterprise expense approval scenario demonstrating all 6 DecisionEffects.
214
+
215
+ Run: `python examples/05_enterprise_expense.py`
214
216
 
215
217
  ## Roadmap
216
218
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
7
- [![Tests: 234](https://img.shields.io/badge/tests-213-brightgreen.svg)](https://github.com/kylecui/petfishFramework/tree/master/tests/)
7
+ [![Tests: 234](https://img.shields.io/badge/tests-234-brightgreen.svg)](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
 
@@ -181,7 +181,9 @@ print(result.summary())
181
181
 
182
182
  ## Enterprise PoC
183
183
 
184
- See `examples/05_enterprise_expense.py` (coming in v0.2.0 release) and `tests/test_enterprise_demo.py` for a complete enterprise expense approval scenario demonstrating all 6 DecisionEffects.
184
+ See `examples/05_enterprise_expense.py` and `tests/test_enterprise_demo.py` for a complete enterprise expense approval scenario demonstrating all 6 DecisionEffects.
185
+
186
+ Run: `python examples/05_enterprise_expense.py`
185
187
 
186
188
  ## Roadmap
187
189
 
@@ -1,6 +1,6 @@
1
1
  # petfishFramework API Reference
2
2
 
3
- This document is the authoritative reference for the public API of `petfishFramework` v0.1.9. Every signature, field, and example below is derived from the source code and from the tests that exercise it.
3
+ This document is the authoritative reference for the public API of `petfishFramework` v0.2.2. Every signature, field, and example below is derived from the source code and from the tests that exercise it.
4
4
 
5
5
  ## 1. Overview
6
6
 
@@ -327,7 +327,7 @@ class Session:
327
327
 
328
328
  `run` builds the `RuntimeEnvironment` and `RunContext`, emits `session.start`, executes the strategy, attaches accumulated `Usage` and `session_id`, and emits `session.end`.
329
329
 
330
- `replay` accepts an optional `ReplayMode` argument. In v0.1.9 all modes return the stored event log; full deterministic replay via `RecordingEnvironment` and `ReplayEnvironment` is available in `petfishframework.reliability.replay`.
330
+ `replay` accepts an optional `ReplayMode` argument. In v0.2.2 all modes return the stored event log; full deterministic replay via `RecordingEnvironment` and `ReplayEnvironment` is available in `petfishframework.reliability.replay`.
331
331
 
332
332
  ```python
333
333
  agent = Agent(model=FakeModel(responses=(ModelResponse(content="ok"),)))
@@ -0,0 +1,92 @@
1
+ # Enterprise Expense Approval Demo
2
+
3
+ > Demonstrates ALL 6 DecisionEffects in a single enterprise scenario.
4
+
5
+ ## Overview
6
+
7
+ This demo shows petfishFramework as a **runtime control framework** — not a calculator framework. An enterprise expense approval agent processes reimbursement requests with full permission gating, budget enforcement, and audit reporting.
8
+
9
+ ## Run
10
+
11
+ ```bash
12
+ python examples/05_enterprise_expense.py
13
+ ```
14
+
15
+ No API key required — uses FakeModel for deterministic, zero-cost execution.
16
+
17
+ ## Scenarios
18
+
19
+ ### 1. ALLOW + PARTIAL_ALLOW
20
+
21
+ **Scenario**: Employee submits $350 team lunch expense.
22
+
23
+ - `check_policy` tool executes (ALLOW)
24
+ - Only `amount` field passed to tool; `secret` field filtered (PARTIAL_ALLOW)
25
+ - Tool sees: `{"amount": 350}` — no sensitive data leaked
26
+
27
+ ### 2. MASK
28
+
29
+ **Scenario**: Payment approval with recipient email.
30
+
31
+ - `approve_payment` has `side_effect=True` → blocked by REQUIRE_APPROVAL first
32
+ - When MASK policy is applied: `recipient` field masked in input args, tool result, and audit log
33
+ - Tool sees: `{"recipient": "[MASKED]", "amount": 300}`
34
+
35
+ ### 3. REQUIRE_APPROVAL
36
+
37
+ **Scenario**: $2000 conference expense.
38
+
39
+ - `approve_payment` has `side_effect=True`
40
+ - Policy returns REQUIRE_APPROVAL before execution
41
+ - Tool does NOT execute — `approve_calls == 0`
42
+ - Event: `tool.approval_required`
43
+
44
+ ### 4. DENY
45
+
46
+ **Scenario**: Non-finance user attempts to approve payment.
47
+
48
+ - Policy checks `subject.roles` for "finance"
49
+ - Non-finance user → DENY
50
+ - Tool does NOT execute
51
+ - Event: `tool.blocked`
52
+
53
+ ### 5. DEGRADE with fallback
54
+
55
+ **Scenario**: $8000 equipment expense.
56
+
57
+ - Amount > $5000 → DEGRADE
58
+ - `fallback_tool="dry_run_payment"` → original tool NOT executed
59
+ - Fallback tool executes instead
60
+ - Event: `tool.degraded` with `original_executed=False, fallback_executed=True`
61
+
62
+ ## AuditReport
63
+
64
+ After each scenario, an AuditReport is generated with:
65
+
66
+ - Summary (session ID, tokens, cost, steps)
67
+ - Event Count by Type
68
+ - Permission Summary (by effect)
69
+ - Budget (input/output tokens, cost)
70
+ - Timeline (tool events with duration)
71
+ - Masked Fields summary
72
+ - Permission Decisions
73
+ - Errors (if any)
74
+ - Final Output
75
+
76
+ ## Policy Design
77
+
78
+ The `ExpensePolicy` uses tool metadata for decisions:
79
+
80
+ | Condition | Effect | Reason |
81
+ |---|---|---|
82
+ | Non-finance + approve_payment | DENY | role-based access control |
83
+ | Tool with side_effect=True | REQUIRE_APPROVAL | safety gate |
84
+ | Amount > $5000 | DEGRADE → dry-run | risk threshold |
85
+ | PII in args (recipient) | MASK | data protection |
86
+ | check_policy | PARTIAL_ALLOW (amount only) | least privilege |
87
+ | Otherwise | ALLOW | default |
88
+
89
+ ## Files
90
+
91
+ - `examples/05_enterprise_expense.py` — runnable demo
92
+ - `tests/test_enterprise_demo.py` — TDD tests (6 tests)