petfishframework 0.3.3__tar.gz → 0.4.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.4.0/.sisyphus/plans/v0.4.0-plan.md +236 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/CHANGELOG.md +29 -0
- petfishframework-0.4.0/Dockerfile +7 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/PKG-INFO +12 -7
- {petfishframework-0.3.3 → petfishframework-0.4.0}/README.md +6 -6
- petfishframework-0.4.0/docker-compose.yml +8 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/api.md +25 -1
- petfishframework-0.4.0/docs/deployment.md +181 -0
- petfishframework-0.4.0/docs/release-protocol.md +86 -0
- petfishframework-0.4.0/docs/threat-model.md +189 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/pyproject.toml +3 -1
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/__init__.py +1 -1
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/environment.py +12 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/session.py +38 -4
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/credentials/__init__.py +2 -1
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/credentials/broker.py +12 -0
- petfishframework-0.4.0/src/petfishframework/credentials/vault_adapter.py +87 -0
- petfishframework-0.4.0/src/petfishframework/observability/otel_sink.py +111 -0
- petfishframework-0.4.0/src/petfishframework/observability/siem_sink.py +113 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/__init__.py +4 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/replay.py +109 -0
- petfishframework-0.4.0/tests/test_otel_sink.py +87 -0
- petfishframework-0.4.0/tests/test_replay_rerun.py +162 -0
- petfishframework-0.4.0/tests/test_replay_resume.py +185 -0
- petfishframework-0.4.0/tests/test_siem_export.py +114 -0
- petfishframework-0.4.0/tests/test_vault_adapter.py +79 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/uv.lock +63 -2
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.env.example +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.github/workflows/ci.yml +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.github/workflows/publish.yml +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.gitignore +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.sisyphus/plans/v0.1.6-plan.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.sisyphus/plans/v0.2.0-plan.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/.sisyphus/plans/v0.3.0-plan.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/AGENTS.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/AGENTS.md.new +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/CONTRIBUTING.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/LICENSE +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/SECURITY.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/conftest.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/architecture.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/benchmark-results.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/development-plan.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/development.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/enterprise-expense-demo.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_0_1_4_playground_recommendations.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_playground_report.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_production_readiness_roadmap.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_recommendations.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_v0_1_6_playground_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_v0_1_7_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_v0_1_8_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_v0_2_1_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/archives/petfishframework_v0_2_2_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/feedbacks/petfishframework_v0_3_0_review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/release-checklist.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/competitor-analysis/README.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/competitor-analysis/competitor-matrix.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/competitor-analysis/market-brief.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/competitor-analysis/positioning-map.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/competitor-analysis/swot-analysis.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/literature-review/inclusion-exclusion-criteria.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/literature-review/literature-matrix.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/literature-review/literature-review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/literature-review/search-strategy.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/research/reference-repos-absorption.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/skeleton-completeness-checklist.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/test-results-report.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/usage-guide.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/docs/validation-roadmap.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/initialization-report.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/mcp/README.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/mcp/connection-checklist.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/mcp/mcp-config.example.json +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/opencode.json +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/qa/code-review-checklist.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/qa/qa-review.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/qa/qc-gate-decision.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/qa/test-plan.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/config.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/agent.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/compiled.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/contracts.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/conversation.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/events.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/structured.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/core/types.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/credentials/token.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/mcp/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/mcp/client.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/mcp/server.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/mcp/stdio_transport.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/mcp/wrapper.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/models/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/models/anthropic.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/models/fake.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/models/openai.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/observability/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/observability/sinks.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/permissions/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/permissions/model.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/conditions.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/engine.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/rule.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/test_runner.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/policies/validator.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reasoning/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reasoning/lats.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reasoning/llm_plus_p.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reasoning/react.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/audit_report.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/cost.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/cost_report.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/pass_at_k.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/retry.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/reliability/timeout.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/retrieval/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/retrieval/adaptive.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/retrieval/crag.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/retrieval/memory_store.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/agent_tool.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/base.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/calculator.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/path_planner.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/registry.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/src/petfishframework/tools/word_sorter.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tasks/backlog.md +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/integration/__init__.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/integration/test_anthropic_integration.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/integration/test_openai_integration.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/policies/enterprise-expense.tests.yaml +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_agent_tool.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_anthropic_adapter.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_api_agent_lifecycle.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_api_edge_cases.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_api_integration.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_api_public_surface.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_api_type_safety.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_async.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_audit_report_v2.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_conversation.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_credential_broker.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_credential_integration.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_degrade.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_degrade_failclosed.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_enterprise_demo.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_m2_m3_m4.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_mcp.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_openai_adapter.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_pass_at_k.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_permission_semantics.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_quickstart_smoke.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_replay.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_retrieval.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_retry.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_skeleton.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_stdio_transport.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_streaming.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_structured.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_tool_registry.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v016_semantics.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v018.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v019.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v2_interface_compatibility.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v2_lats.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_v2_llm_plus_p.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_yaml_policy.py +0 -0
- {petfishframework-0.3.3 → petfishframework-0.4.0}/tests/test_yaml_policy_suite.py +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# petfishFramework v0.4.0 开发计划
|
|
2
|
+
|
|
3
|
+
> 基于 v0.3.3 状态 + 8 轮用户反馈 + 全部 deferred 项汇总
|
|
4
|
+
> 目标:observability + deterministic replay + 生产化基础
|
|
5
|
+
> 原则:**TDD 先行,pre_release.py 门禁,文档同步作为完成条件**
|
|
6
|
+
|
|
7
|
+
## v0.4.0 使命
|
|
8
|
+
|
|
9
|
+
> 让 Agent 运行时可观测(OTel)、可回放(确定性 RERUN/RESUME)、可治理(SIEM export)、可部署(Docker + 部署指南)。
|
|
10
|
+
|
|
11
|
+
## Deferred 项汇总(从全部反馈中提取)
|
|
12
|
+
|
|
13
|
+
| 来源 | Deferred 项 | v0.4.0 目标 |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| v0.3.0 §9.2 | deterministic rerun / resume | ✅ 实现 |
|
|
16
|
+
| v0.3.0 §9.2 | MCP server mode | ⏳ v0.5.0(需完整 MCP server 实现) |
|
|
17
|
+
| v0.3.0 §9.2 | deployment guide | ✅ Dockerfile + 部署文档 |
|
|
18
|
+
| v0.3.0 §9.2 | OpenTelemetry | ✅ OTelSink |
|
|
19
|
+
| v0.3.0 §9.2 | SIEM export | ✅ JSON-Lines trace export |
|
|
20
|
+
| v0.3.0 §P2 | Vault adapter | ✅ HashiCorp Vault adapter (可选) |
|
|
21
|
+
| v0.3.0 §P2 | threat model | ✅ 威胁模型文档 |
|
|
22
|
+
| v0.3.0 §P2 | SBOM | ✅ cyclonedx 生成 |
|
|
23
|
+
| v0.3.0 §P2 | signed release | ✅ sigstore cosign |
|
|
24
|
+
| 多轮 | README Current Limitations 中 planned 项 | 清理为 available |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Phase A: Deterministic Replay (RESUME + RERUN)
|
|
29
|
+
|
|
30
|
+
### A1: RESUME — 检查点恢复
|
|
31
|
+
|
|
32
|
+
**目标**:从检查点恢复执行,重注入已记录的模型响应直到检查点,之后继续新鲜调用。
|
|
33
|
+
|
|
34
|
+
#### TDD 测试先行
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
# tests/test_replay_resume.py
|
|
38
|
+
|
|
39
|
+
def test_resume_replays_recorded_prefix():
|
|
40
|
+
"""RESUME: 重注入检查点前的模型响应。"""
|
|
41
|
+
|
|
42
|
+
def test_resume_continues_with_fresh_calls():
|
|
43
|
+
"""RESUME: 检查点后用 live environment 新鲜调用。"""
|
|
44
|
+
|
|
45
|
+
def test_resume_from_mid_session():
|
|
46
|
+
"""RESUME: 从 Session 中间的检查点恢复。"""
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### 实现
|
|
50
|
+
|
|
51
|
+
- `ResumableEnvironment`(已有 v0.1.x 基础)增强:
|
|
52
|
+
- `checkpoint_model_idx` / `checkpoint_tool_idx` 参数
|
|
53
|
+
- 检查点前用 `recording.model_responses[i]` 重注入
|
|
54
|
+
- 检查点后切换到 `live_env`
|
|
55
|
+
- `Session.checkpoint()` 发出 `session.checkpoint` 事件 + 记录当前 model/tool 索引
|
|
56
|
+
- `Session.resume_from(checkpoint_data)` 工厂方法
|
|
57
|
+
|
|
58
|
+
### A2: RERUN — 确定性完整重放 + 偏离检测
|
|
59
|
+
|
|
60
|
+
**目标**:完整重放一个 Session 的所有调用,验证轨迹一致。偏离时报告差异。
|
|
61
|
+
|
|
62
|
+
#### TDD 测试先行
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# tests/test_replay_rerun.py
|
|
66
|
+
|
|
67
|
+
def test_rerun_reproduces_identical_trajectory():
|
|
68
|
+
"""RERUN: 完整重放,轨迹完全一致。"""
|
|
69
|
+
|
|
70
|
+
def test_rerun_detects_model_call_count_divergence():
|
|
71
|
+
"""RERUN: 模型调用次数不一致 → 报告偏离。"""
|
|
72
|
+
|
|
73
|
+
def test_rerun_detects_tool_result_divergence():
|
|
74
|
+
"""RERUN: 工具结果不一致 → 报告偏离。"""
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### 实现
|
|
78
|
+
|
|
79
|
+
- `RerunEnvironment`:封装 `RecordingEnvironment` + `ReplayEnvironment`
|
|
80
|
+
- `rerun() -> RerunResult`:重放 + 比对
|
|
81
|
+
- `RerunResult.matches: bool` + `divergences: list[str]`
|
|
82
|
+
- 检测:调用次数偏离、工具名偏离、结果值偏离
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Phase B: Observability
|
|
87
|
+
|
|
88
|
+
### B1: OpenTelemetry Sink
|
|
89
|
+
|
|
90
|
+
**目标**:Session 事件 → OTel spans,可接入 Jaeger/Zipkin/DataDog。
|
|
91
|
+
|
|
92
|
+
#### TDD 测试先行
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
# tests/test_otel_sink.py
|
|
96
|
+
|
|
97
|
+
def test_otel_sink_creates_span_per_tool_call():
|
|
98
|
+
"""每个 tool.called 事件创建一个 span。"""
|
|
99
|
+
|
|
100
|
+
def test_otel_sink_creates_span_per_model_call():
|
|
101
|
+
"""每个 model.called 事件创建一个 span。"""
|
|
102
|
+
|
|
103
|
+
def test_otel_sink_nests_tool_spans_under_session():
|
|
104
|
+
"""工具 span 嵌套在 session trace 下。"""
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### 实现
|
|
108
|
+
|
|
109
|
+
- `observability/otel_sink.py` — `OTelSink`:
|
|
110
|
+
- 接收 EventEmitter 事件
|
|
111
|
+
- Session → OTel Trace
|
|
112
|
+
- model.called → span (attributes: model name, tokens, cost)
|
|
113
|
+
- tool.called/blocked/masked → span (attributes: tool name, effect, duration)
|
|
114
|
+
- 使用 `opentelemetry-api`(可选依赖:`pip install petfishframework[otel]`)
|
|
115
|
+
- 无 OTel 安装时降级为 no-op
|
|
116
|
+
|
|
117
|
+
### B2: SIEM Export (JSON-Lines Trace)
|
|
118
|
+
|
|
119
|
+
**目标**:结构化事件导出,可导入 Splunk/Elastic/Datadog。
|
|
120
|
+
|
|
121
|
+
#### TDD 测试先行
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
# tests/test_siem_export.py
|
|
125
|
+
|
|
126
|
+
def test_siem_export_produces_jsonlines():
|
|
127
|
+
"""导出为 JSON-Lines 格式。"""
|
|
128
|
+
|
|
129
|
+
def test_siem_export_redacts_credentials():
|
|
130
|
+
"""导出中不含 secret。"""
|
|
131
|
+
|
|
132
|
+
def test_siem_export_includes_policy_version():
|
|
133
|
+
"""每条记录包含 policy_version。"""
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### 实现
|
|
137
|
+
|
|
138
|
+
- `observability/siem_sink.py` — `SIEMSink`:
|
|
139
|
+
- 接收事件 → 写入 JSON-Lines 文件/流
|
|
140
|
+
- 每行:`{"timestamp", "session_id", "event_type", "tool_name", "effect", "executed", "policy_version", "duration_ms"}`
|
|
141
|
+
- 自动脱敏(复用 event_mask 逻辑)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Phase C: Production Foundation
|
|
146
|
+
|
|
147
|
+
### C1: Vault Adapter
|
|
148
|
+
|
|
149
|
+
**目标**:CredentialBroker 支持 HashiCorp Vault 作为 secret 后端。
|
|
150
|
+
|
|
151
|
+
#### TDD 测试先行
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# tests/test_vault_adapter.py
|
|
155
|
+
|
|
156
|
+
def test_vault_adapter_reads_secret():
|
|
157
|
+
"""Vault adapter 从 Vault 读取 secret。"""
|
|
158
|
+
# 使用 mock,不连真实 Vault
|
|
159
|
+
|
|
160
|
+
def test_vault_adapter_caches_locally():
|
|
161
|
+
"""读取后缓存,减少 Vault 调用。"""
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### 实现
|
|
165
|
+
|
|
166
|
+
- `credentials/vault_adapter.py` — `VaultCredentialSource`:
|
|
167
|
+
- `read_secret(path: str) -> str` — 从 Vault 读取
|
|
168
|
+
- 可选依赖:`hvac` library
|
|
169
|
+
- 集成到 `CredentialBroker.register_credential_from_vault(path)`
|
|
170
|
+
|
|
171
|
+
### C2: Dockerfile + 部署指南
|
|
172
|
+
|
|
173
|
+
**文件**:
|
|
174
|
+
- `Dockerfile` — 多阶段构建
|
|
175
|
+
- `docker-compose.yml` — 开发环境
|
|
176
|
+
- `docs/deployment.md` — 部署指南
|
|
177
|
+
|
|
178
|
+
### C3: SBOM + Signed Release
|
|
179
|
+
|
|
180
|
+
- `.github/workflows/publish.yml` 增强:
|
|
181
|
+
- 生成 SBOM (cyclonedx)
|
|
182
|
+
- cosign 签名
|
|
183
|
+
- `docs/threat-model.md` — 威胁模型
|
|
184
|
+
|
|
185
|
+
### C4: 文档 + README 更新
|
|
186
|
+
|
|
187
|
+
- api.md: 新增 OTel + SIEM + Vault + Replay 章节
|
|
188
|
+
- README: Current Limitations 清理(deterministic replay: Available; OTel: Available)
|
|
189
|
+
- CHANGELOG: v0.4.0
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 执行顺序与依赖
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
A1 (RESUME) → A2 (RERUN)
|
|
197
|
+
↓
|
|
198
|
+
B1 (OTel) → B2 (SIEM)
|
|
199
|
+
↓
|
|
200
|
+
C1 (Vault) → C2 (Docker) → C3 (SBOM) → C4 (docs)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## 验收标准
|
|
204
|
+
|
|
205
|
+
| # | 标准 | 验证方法 |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| V1 | RESUME 从检查点恢复执行 | `test_replay_resume.py` |
|
|
208
|
+
| V2 | RERUN 完整重放 + 偏离检测 | `test_replay_rerun.py` |
|
|
209
|
+
| V3 | OTel sink 生成 spans | `test_otel_sink.py` |
|
|
210
|
+
| V4 | SIEM 导出 JSON-Lines + 脱敏 | `test_siem_export.py` |
|
|
211
|
+
| V5 | Vault adapter 读取 secret(mock) | `test_vault_adapter.py` |
|
|
212
|
+
| V6 | Dockerfile 可构建 | `docker build .` |
|
|
213
|
+
| V7 | SBOM 生成 | CI workflow |
|
|
214
|
+
| V8 | pre_release.py exit 0 | `python scripts/pre_release.py 0.4.0` |
|
|
215
|
+
| V9 | 所有 284+ 现有测试通过 | pytest |
|
|
216
|
+
| V10 | ruff clean | ruff check |
|
|
217
|
+
| V11 | README Current Limitations 清理 | grep "Planned" |
|
|
218
|
+
|
|
219
|
+
## 不做清单(v0.5.0+)
|
|
220
|
+
|
|
221
|
+
- ❌ MCP server mode
|
|
222
|
+
- ❌ MCP governance (allowlist, rate limit)
|
|
223
|
+
- ❌ Tool sandbox (subprocess isolation)
|
|
224
|
+
- ❌ Policy hot-reload
|
|
225
|
+
- ❌ Multi-tenant policy namespace
|
|
226
|
+
|
|
227
|
+
## 新测试预估
|
|
228
|
+
|
|
229
|
+
| Phase | 测试数 |
|
|
230
|
+
|---|---|
|
|
231
|
+
| A1 RESUME | 3 |
|
|
232
|
+
| A2 RERUN | 3 |
|
|
233
|
+
| B1 OTel | 3 |
|
|
234
|
+
| B2 SIEM | 3 |
|
|
235
|
+
| C1 Vault | 2 |
|
|
236
|
+
| **总计** | **~14 新测试** |
|
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to petfishFramework will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.4.0] — 2026-07-08
|
|
6
|
+
|
|
7
|
+
### v0.4.0 Production Foundation
|
|
8
|
+
|
|
9
|
+
#### Phase A+B: Deterministic Replay + Observability
|
|
10
|
+
- Deterministic replay infrastructure (`petfishframework.reliability.replay`):
|
|
11
|
+
- `RecordingEnvironment` captures every model response, tool call, and retrieval
|
|
12
|
+
- `ReplayEnvironment` replays recorded calls for deterministic audit
|
|
13
|
+
- `ResumableEnvironment` replays prefix then switches to live execution
|
|
14
|
+
- `ReplayMode.AUDIT`, `RESUME`, `RERUN` semantics
|
|
15
|
+
- OpenTelemetry sink (`OTelSink`) — creates spans for model/tool/session events
|
|
16
|
+
- SIEM export (`SIEMSink`) — structured JSON audit events for downstream SIEMs
|
|
17
|
+
|
|
18
|
+
#### Phase C: Vault Adapter + Deployment + Threat Model
|
|
19
|
+
- `VaultCredentialSource` — reads secrets from HashiCorp Vault with lazy `hvac` import
|
|
20
|
+
- `CredentialBroker.register_credential_from_vault(name, source, path)` — register
|
|
21
|
+
credentials fetched from Vault
|
|
22
|
+
- Optional dependency group `vault = ["hvac>=1.0"]`
|
|
23
|
+
- `Dockerfile` and `docker-compose.yml` for containerized deployment
|
|
24
|
+
- `docs/deployment.md` — Docker deployment guide, environment variables, volume mounts,
|
|
25
|
+
credential-broker integration, and security notes
|
|
26
|
+
- `docs/threat-model.md` — attack surface, trust boundaries, threats, mitigations,
|
|
27
|
+
and fail-closed defaults
|
|
28
|
+
|
|
29
|
+
#### Documentation Sync
|
|
30
|
+
- `docs/api.md` updated to v0.4.0
|
|
31
|
+
- README: deterministic replay and OTel marked available, roadmap bumped to v0.4.x
|
|
32
|
+
- Test count badge updated to 300
|
|
33
|
+
|
|
5
34
|
## [0.3.2] — 2026-07-08
|
|
6
35
|
|
|
7
36
|
### YAML Policy DSL Expansion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: petfishframework
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -26,6 +26,11 @@ Provides-Extra: mcp
|
|
|
26
26
|
Requires-Dist: mcp>=1.0; extra == 'mcp'
|
|
27
27
|
Provides-Extra: openai
|
|
28
28
|
Requires-Dist: openai>=1.0; extra == 'openai'
|
|
29
|
+
Provides-Extra: otel
|
|
30
|
+
Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
|
|
31
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'otel'
|
|
32
|
+
Provides-Extra: vault
|
|
33
|
+
Requires-Dist: hvac>=1.0; extra == 'vault'
|
|
29
34
|
Description-Content-Type: text/markdown
|
|
30
35
|
|
|
31
36
|
# petfishFramework
|
|
@@ -34,7 +39,7 @@ Description-Content-Type: text/markdown
|
|
|
34
39
|
|
|
35
40
|
[](https://www.python.org/downloads/)
|
|
36
41
|
[](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
|
|
37
|
-
[](https://github.com/kylecui/petfishFramework/tree/master/tests/)
|
|
38
43
|
|
|
39
44
|
**Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
|
|
40
45
|
|
|
@@ -247,8 +252,8 @@ agent = Agent(model=model, reasoning=ReAct(), tools=tools, credential_broker=bro
|
|
|
247
252
|
## Roadmap
|
|
248
253
|
|
|
249
254
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
250
|
-
- **v0.3.x
|
|
251
|
-
- **v0.4.x
|
|
255
|
+
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
256
|
+
- **v0.4.x** (current): Production hardening, deployment guides, Vault adapter, Docker, threat model ✅
|
|
252
257
|
|
|
253
258
|
## Current Limitations
|
|
254
259
|
|
|
@@ -263,8 +268,8 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
263
268
|
| PARTIAL_ALLOW | ✅ Enforced (pre-execution arg filtering) |
|
|
264
269
|
| MASK | ✅ Enforced (input mask before + output mask after) |
|
|
265
270
|
| DEGRADE | ✅ Enforced (fallback tool switching) |
|
|
266
|
-
| Session replay
|
|
267
|
-
|
|
|
271
|
+
| Session replay / deterministic rerun / resume | ✅ Available |
|
|
272
|
+
| OpenTelemetry + SIEM observability | ✅ Available |
|
|
268
273
|
| MCP client stdio | ✅ Available |
|
|
269
274
|
| MCP server mode | 📋 Planned |
|
|
270
275
|
| Structured output / conversation memory | ✅ Available |
|
|
@@ -279,7 +284,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
279
284
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
280
285
|
cd petfishFramework
|
|
281
286
|
uv sync --all-extras
|
|
282
|
-
uv run pytest #
|
|
287
|
+
uv run pytest # 300 tests
|
|
283
288
|
uv run ruff check src/ tests/
|
|
284
289
|
```
|
|
285
290
|
|
|
@@ -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
|
|
|
@@ -217,8 +217,8 @@ agent = Agent(model=model, reasoning=ReAct(), tools=tools, credential_broker=bro
|
|
|
217
217
|
## Roadmap
|
|
218
218
|
|
|
219
219
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
220
|
-
- **v0.3.x
|
|
221
|
-
- **v0.4.x
|
|
220
|
+
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
221
|
+
- **v0.4.x** (current): Production hardening, deployment guides, Vault adapter, Docker, threat model ✅
|
|
222
222
|
|
|
223
223
|
## Current Limitations
|
|
224
224
|
|
|
@@ -233,8 +233,8 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
233
233
|
| PARTIAL_ALLOW | ✅ Enforced (pre-execution arg filtering) |
|
|
234
234
|
| MASK | ✅ Enforced (input mask before + output mask after) |
|
|
235
235
|
| DEGRADE | ✅ Enforced (fallback tool switching) |
|
|
236
|
-
| Session replay
|
|
237
|
-
|
|
|
236
|
+
| Session replay / deterministic rerun / resume | ✅ Available |
|
|
237
|
+
| OpenTelemetry + SIEM observability | ✅ Available |
|
|
238
238
|
| MCP client stdio | ✅ Available |
|
|
239
239
|
| MCP server mode | 📋 Planned |
|
|
240
240
|
| Structured output / conversation memory | ✅ Available |
|
|
@@ -249,7 +249,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
249
249
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
250
250
|
cd petfishFramework
|
|
251
251
|
uv sync --all-extras
|
|
252
|
-
uv run pytest #
|
|
252
|
+
uv run pytest # 300 tests
|
|
253
253
|
uv run ruff check src/ tests/
|
|
254
254
|
```
|
|
255
255
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# petfishFramework API Reference
|
|
2
2
|
|
|
3
|
-
This document is the authoritative reference for the public API of
|
|
3
|
+
This document is the authoritative reference for the public API of petfishFramework v0.4.0. 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
|
|
|
@@ -1445,3 +1445,27 @@ token.get_secret() # raises ValueError("max uses exceeded")
|
|
|
1445
1445
|
if session.credential_broker:
|
|
1446
1446
|
session.credential_broker.cleanup_expired()
|
|
1447
1447
|
```
|
|
1448
|
+
|
|
1449
|
+
### Vault Integration (v0.4.0)
|
|
1450
|
+
|
|
1451
|
+
```python
|
|
1452
|
+
from petfishframework.credentials import CredentialBroker, VaultCredentialSource
|
|
1453
|
+
|
|
1454
|
+
broker = CredentialBroker()
|
|
1455
|
+
source = VaultCredentialSource(
|
|
1456
|
+
vault_url="https://vault.example.com",
|
|
1457
|
+
token="hvs.CAES...",
|
|
1458
|
+
)
|
|
1459
|
+
broker.register_credential_from_vault("openai", source, path="secrets/openai")
|
|
1460
|
+
```
|
|
1461
|
+
|
|
1462
|
+
`VaultCredentialSource` performs a lazy import of `hvac` and raises a clear
|
|
1463
|
+
`ImportError` if the optional dependency is missing. The secret is read once and
|
|
1464
|
+
cached locally for the lifetime of the source; subsequent reads of the same
|
|
1465
|
+
path do not call Vault again.
|
|
1466
|
+
|
|
1467
|
+
Install the optional dependency with:
|
|
1468
|
+
|
|
1469
|
+
```bash
|
|
1470
|
+
pip install petfishframework[vault]
|
|
1471
|
+
```
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide covers running petfishFramework in production using Docker and
|
|
4
|
+
Docker Compose.
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
Build and run the container:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
docker build -t petfishframework .
|
|
12
|
+
docker run --rm -e OPENAI_API_KEY=$OPENAI_API_KEY petfishframework
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
With Docker Compose:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
docker compose up --build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Dockerfile
|
|
22
|
+
|
|
23
|
+
The included `Dockerfile` uses a multi-stage style with `uv`:
|
|
24
|
+
|
|
25
|
+
1. Copies `pyproject.toml` and `uv.lock` first for layer caching.
|
|
26
|
+
2. Installs production dependencies with `uv sync --no-dev`.
|
|
27
|
+
3. Copies the `src/` directory and installs the package itself.
|
|
28
|
+
4. Uses `ENTRYPOINT ["python", "-m", "petfishframework"]`.
|
|
29
|
+
|
|
30
|
+
To build for a specific Python version, change the base image tag:
|
|
31
|
+
|
|
32
|
+
```dockerfile
|
|
33
|
+
FROM python:3.11-slim
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Environment Variables
|
|
37
|
+
|
|
38
|
+
The container reads configuration from environment variables. Required and
|
|
39
|
+
commonly used variables:
|
|
40
|
+
|
|
41
|
+
| Variable | Purpose | Example |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `OPENAI_API_KEY` | API key for OpenAI-compatible models | `sk-...` |
|
|
44
|
+
| `OPENAI_BASE_URL` | Custom base URL for OpenAI-compatible endpoints | `https://api.siliconflow.cn/v1` |
|
|
45
|
+
| `ANTHROPIC_API_KEY` | API key for Anthropic models | `sk-ant-...` |
|
|
46
|
+
| `VAULT_ADDR` | HashiCorp Vault URL when using `VaultCredentialSource` | `https://vault.example.com` |
|
|
47
|
+
| `VAULT_TOKEN` | Vault token (alternative to passing it in code) | `hvs.CAES...` |
|
|
48
|
+
|
|
49
|
+
Pass variables with `-e`:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
docker run --rm \
|
|
53
|
+
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
|
54
|
+
-e OPENAI_BASE_URL=$OPENAI_BASE_URL \
|
|
55
|
+
petfishframework
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or use an `.env` file:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
docker run --rm --env-file .env petfishframework
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Volume Mounts
|
|
65
|
+
|
|
66
|
+
Mount directories that the framework needs at runtime:
|
|
67
|
+
|
|
68
|
+
### Examples and local policies
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
docker run --rm \
|
|
72
|
+
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
|
73
|
+
-v $(pwd)/examples:/app/examples \
|
|
74
|
+
-v $(pwd)/policies:/app/policies \
|
|
75
|
+
petfishframework python examples/05_enterprise_expense.py
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Credentials and secrets
|
|
79
|
+
|
|
80
|
+
Do **not** bake credentials into the image. Instead, use one of these
|
|
81
|
+
approaches:
|
|
82
|
+
|
|
83
|
+
1. **Environment variables** — simplest for container runtimes.
|
|
84
|
+
2. **Secret mounts** — Docker secrets or Kubernetes secrets mounted as files.
|
|
85
|
+
3. **Vault integration** — use `VaultCredentialSource` to fetch secrets at
|
|
86
|
+
startup; see the [Credential Broker](#credential-broker) section below.
|
|
87
|
+
|
|
88
|
+
For policy files, YAML policy engine, and example scripts, mount a read-only
|
|
89
|
+
volume:
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
volumes:
|
|
93
|
+
- ./examples:/app/examples:ro
|
|
94
|
+
- ./policies:/app/policies:ro
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Docker Compose
|
|
98
|
+
|
|
99
|
+
The included `docker-compose.yml` starts a single `agent` service:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
version: "3.9"
|
|
103
|
+
services:
|
|
104
|
+
agent:
|
|
105
|
+
build: .
|
|
106
|
+
environment:
|
|
107
|
+
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
108
|
+
volumes:
|
|
109
|
+
- ./examples:/app/examples
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Override it with a `docker-compose.override.yml` for local secrets or extra
|
|
113
|
+
mounts:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
services:
|
|
117
|
+
agent:
|
|
118
|
+
environment:
|
|
119
|
+
- VAULT_ADDR=https://vault.example.com
|
|
120
|
+
secrets:
|
|
121
|
+
- vault_token
|
|
122
|
+
|
|
123
|
+
secrets:
|
|
124
|
+
vault_token:
|
|
125
|
+
file: ./secrets/vault_token
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Credential Broker
|
|
129
|
+
|
|
130
|
+
Use `CredentialBroker` with `VaultCredentialSource` to avoid passing raw secrets
|
|
131
|
+
through environment variables:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from petfishframework.credentials import CredentialBroker, VaultCredentialSource
|
|
135
|
+
|
|
136
|
+
broker = CredentialBroker()
|
|
137
|
+
source = VaultCredentialSource(
|
|
138
|
+
vault_url="https://vault.example.com",
|
|
139
|
+
token="hvs.CAES...",
|
|
140
|
+
)
|
|
141
|
+
broker.register_credential_from_vault("openai", source, path="secrets/openai")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The Vault source reads the secret once, caches it locally for the lifetime of
|
|
145
|
+
the process, and issues scoped, time-limited tokens to tools. The underlying
|
|
146
|
+
`hvac` package is optional; install it with:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
pip install petfishframework[vault]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Security Notes
|
|
153
|
+
|
|
154
|
+
- Keep images small: only production dependencies are installed (`--no-dev`).
|
|
155
|
+
- Do not commit API keys, tokens, or `.env` files to version control.
|
|
156
|
+
- Mount credential files as read-only volumes or Docker secrets.
|
|
157
|
+
- Run the container with the least-privilege user when possible:
|
|
158
|
+
|
|
159
|
+
```dockerfile
|
|
160
|
+
RUN useradd -m appuser
|
|
161
|
+
USER appuser
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- Event logs may contain sensitive arguments. Enable `MASK` policies to
|
|
165
|
+
redact PII and secrets from audit events.
|
|
166
|
+
- For Vault, use short-lived tokens and rotate them via your orchestrator.
|
|
167
|
+
|
|
168
|
+
## Health Checks
|
|
169
|
+
|
|
170
|
+
Add a simple health check to long-running services:
|
|
171
|
+
|
|
172
|
+
```dockerfile
|
|
173
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
174
|
+
CMD python -c "import petfishframework; print(petfishframework.__version__)" || exit 1
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Next Steps
|
|
178
|
+
|
|
179
|
+
- See [architecture.md](architecture.md) for runtime design.
|
|
180
|
+
- See [threat-model.md](threat-model.md) for security boundaries.
|
|
181
|
+
- See [api.md](api.md) for the full API reference.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# petfishFramework — 强制发布协议
|
|
2
|
+
|
|
3
|
+
> 这不是建议清单。这是**每次发布必须执行的门禁脚本**。
|
|
4
|
+
> 不执行完不能打 tag。不执行完不能 push。
|
|
5
|
+
|
|
6
|
+
## 自动化脚本:`scripts/pre_release.py`
|
|
7
|
+
|
|
8
|
+
**每次发布前运行**:`python scripts/pre_release.py 0.3.4`
|
|
9
|
+
|
|
10
|
+
脚本自动检查:
|
|
11
|
+
|
|
12
|
+
1. **版本号一致性**(6 处):
|
|
13
|
+
- pyproject.toml version
|
|
14
|
+
- __init__.py __version__
|
|
15
|
+
- api.md 标题版本号
|
|
16
|
+
- README badge URL 数字
|
|
17
|
+
- README badge 文本数字
|
|
18
|
+
- CHANGELOG 最新条目版本号
|
|
19
|
+
|
|
20
|
+
2. **文档完整性**:
|
|
21
|
+
- grep 新增模块名在 api.md 中是否存在
|
|
22
|
+
- grep CHANGELOG 中是否有当前版本条目
|
|
23
|
+
- README roadmap "current" 是否指向当前版本
|
|
24
|
+
|
|
25
|
+
3. **测试 + lint**:
|
|
26
|
+
- pytest 全通过
|
|
27
|
+
- ruff check 通过
|
|
28
|
+
|
|
29
|
+
4. **API 闭合检查**(人工确认):
|
|
30
|
+
- 新功能是否在 Agent 或 Session 上有用户面参数?
|
|
31
|
+
- 新功能是否有 api.md 章节?
|
|
32
|
+
- 新功能是否有 CHANGELOG 条目?
|
|
33
|
+
|
|
34
|
+
退出码 0 = 可以发布;非 0 = 必须修复。
|
|
35
|
+
|
|
36
|
+
## 发布 SOP(严格顺序)
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
1. python scripts/pre_release.py <version>
|
|
40
|
+
↓ (必须 exit 0)
|
|
41
|
+
2. uv run pytest tests/ -q
|
|
42
|
+
↓ (必须全通过)
|
|
43
|
+
3. uv run ruff check src/ tests/ examples/
|
|
44
|
+
↓ (必须 All checks passed)
|
|
45
|
+
4. git add -A && git commit -m "release: v<version>"
|
|
46
|
+
5. git push origin master
|
|
47
|
+
6. git tag v<version> # 必须有 v 前缀!
|
|
48
|
+
7. git push origin v<version>
|
|
49
|
+
8. 等待 CI + Publish 双绿
|
|
50
|
+
9. 验证 https://pypi.org/project/petfishframework/<version>/
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 版本号同步检查表(每次必查)
|
|
54
|
+
|
|
55
|
+
| 位置 | 检查命令 | 预期 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| pyproject.toml | `grep "^version" pyproject.toml` | `version = "X.Y.Z"` |
|
|
58
|
+
| __init__.py | `grep "__version__" src/petfishframework/__init__.py` | `__version__ = "X.Y.Z"` |
|
|
59
|
+
| api.md 标题 | `head -3 docs/api.md` | `vX.Y.Z` |
|
|
60
|
+
| README badge URL | `grep "badge/tests" README.md` | URL 含正确测试数 |
|
|
61
|
+
| README badge 文本 | `grep "Tests:" README.md` | 文本含正确测试数 |
|
|
62
|
+
| CHANGELOG | `head -10 CHANGELOG.md` | `## [X.Y.Z]` 在顶部 |
|
|
63
|
+
|
|
64
|
+
## 新功能检查表(每次加功能必查)
|
|
65
|
+
|
|
66
|
+
| 检查项 | 命令 | 预期 |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| Agent 参数 | 新功能是否在 `Agent.__init__` 有对应参数? | 用户能一行配置 |
|
|
69
|
+
| Session 传递 | Agent 参数是否传到 Session → Environment? | 全链路通 |
|
|
70
|
+
| api.md 章节 | `grep "<新类名>" docs/api.md` | 有匹配 |
|
|
71
|
+
| CHANGELOG 条目 | `grep "<版本号>" CHANGELOG.md` | 有条目 |
|
|
72
|
+
| TDD 测试 | `pytest tests/test_<新功能>.py` | 通过 |
|
|
73
|
+
| 安全边界 | 负面测试:无配置时是否安全降级? | 不崩溃 |
|
|
74
|
+
|
|
75
|
+
## 绝不再犯的错误清单
|
|
76
|
+
|
|
77
|
+
| # | 错误 | 防止机制 |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| 1 | 忘记更新 api.md 版本号 | pre_release.py 自动检查 |
|
|
80
|
+
| 2 | Badge URL 和文本不一致 | pre_release.py 自动检查 |
|
|
81
|
+
| 3 | CHANGELOG 缺当前版本条目 | pre_release.py 自动检查 |
|
|
82
|
+
| 4 | 功能只在内部 hook,Agent 无入口 | 新功能检查表:Agent 参数 |
|
|
83
|
+
| 5 | 安全语义只在正常路径验证 | TDD 必须包含 known-bad(side-effect tracking) |
|
|
84
|
+
| 6 | tag 无 v 前缀 | 发布 SOP 第 6 步明确 v 前缀 |
|
|
85
|
+
| 7 | 新功能无 api.md 章节 | 新功能检查表 |
|
|
86
|
+
| 8 | 使用 twine/token | 已撤销;Trusted Publishing only |
|