proofpacket 0.1.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.
- proofpacket-0.1.0/LICENSE +21 -0
- proofpacket-0.1.0/PKG-INFO +265 -0
- proofpacket-0.1.0/README.md +232 -0
- proofpacket-0.1.0/proofpacket/__init__.py +9 -0
- proofpacket-0.1.0/proofpacket/cli.py +129 -0
- proofpacket-0.1.0/proofpacket/events.py +14 -0
- proofpacket-0.1.0/proofpacket/exporters.py +94 -0
- proofpacket-0.1.0/proofpacket/hashing.py +133 -0
- proofpacket-0.1.0/proofpacket/receipt.py +410 -0
- proofpacket-0.1.0/proofpacket/redaction.py +47 -0
- proofpacket-0.1.0/proofpacket/risk.py +47 -0
- proofpacket-0.1.0/proofpacket/schema/__init__.py +12 -0
- proofpacket-0.1.0/proofpacket/schema/proofpacket.schema.json +138 -0
- proofpacket-0.1.0/proofpacket/wrappers/__init__.py +3 -0
- proofpacket-0.1.0/proofpacket/wrappers/anthropic.py +111 -0
- proofpacket-0.1.0/proofpacket/wrappers/openai.py +120 -0
- proofpacket-0.1.0/proofpacket.egg-info/PKG-INFO +265 -0
- proofpacket-0.1.0/proofpacket.egg-info/SOURCES.txt +29 -0
- proofpacket-0.1.0/proofpacket.egg-info/dependency_links.txt +1 -0
- proofpacket-0.1.0/proofpacket.egg-info/entry_points.txt +2 -0
- proofpacket-0.1.0/proofpacket.egg-info/requires.txt +11 -0
- proofpacket-0.1.0/proofpacket.egg-info/top_level.txt +1 -0
- proofpacket-0.1.0/pyproject.toml +69 -0
- proofpacket-0.1.0/setup.cfg +4 -0
- proofpacket-0.1.0/tests/test_anthropic_wrapper.py +48 -0
- proofpacket-0.1.0/tests/test_cli.py +53 -0
- proofpacket-0.1.0/tests/test_hashing.py +42 -0
- proofpacket-0.1.0/tests/test_openai_wrapper.py +53 -0
- proofpacket-0.1.0/tests/test_receipt.py +199 -0
- proofpacket-0.1.0/tests/test_redaction.py +10 -0
- proofpacket-0.1.0/tests/test_schema_validation.py +21 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ProofPacket Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proofpacket
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Privacy-safe evidence packets for AI agent runs
|
|
5
|
+
Author: ProofPacket Contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ProofPacket/proofpacket
|
|
8
|
+
Project-URL: Documentation, https://github.com/ProofPacket/proofpacket#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/ProofPacket/proofpacket
|
|
10
|
+
Project-URL: Issues, https://github.com/ProofPacket/proofpacket/issues
|
|
11
|
+
Keywords: ai-agents,ai-proof-packet,evidence-packet,audit-trail,llm,compliance,ai-governance
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: typer>=0.12
|
|
25
|
+
Requires-Dist: jsonschema>=4.0
|
|
26
|
+
Provides-Extra: anthropic
|
|
27
|
+
Requires-Dist: anthropic>=0.39; extra == "anthropic"
|
|
28
|
+
Provides-Extra: openai
|
|
29
|
+
Requires-Dist: openai>=1.0; extra == "openai"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<img src="docs/assets/proofpacket-logo.png" alt="ProofPacket logo" width="160">
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
# ProofPacket
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+

|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
## Your AI agent did 47 things. Send your client one proof packet.
|
|
45
|
+
|
|
46
|
+
Local-first. No SaaS account. ProofPacket does not send your packet data to a ProofPacket service.
|
|
47
|
+
|
|
48
|
+
ProofPacket is an open-source Python SDK and JSON schema for privacy-safe evidence packets for AI agent runs and LLM workflows.
|
|
49
|
+
|
|
50
|
+
Use ProofPacket when you need an AI agent audit trail, LLM audit log, AI automation evidence packet, or client-facing proof of what an AI workflow did without storing raw prompts, outputs, files, source URLs, local paths, or secrets.
|
|
51
|
+
|
|
52
|
+
ProofPacket records LLM calls, tool calls, file access, human approvals, sources, risk flags, and hash-chain verification as a shareable evidence packet.
|
|
53
|
+
|
|
54
|
+
v0.1 includes thin wrappers for Anthropic `messages.create(...)` and OpenAI `chat.completions.create(...)`. Other Python LLM workflows can use the SDK directly. LangChain, MCP, and Claude Code integrations are planned.
|
|
55
|
+
|
|
56
|
+
No raw prompts. No file contents. No leaked source URLs or local paths by default. Verifiable.
|
|
57
|
+
|
|
58
|
+
Provider wrappers still call the configured LLM provider. ProofPacket keeps the JSON/Markdown evidence packet local unless you choose to share it.
|
|
59
|
+
|
|
60
|
+

|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
$ proofpacket verify examples/sample_packet.json
|
|
64
|
+
valid
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## The Flagship Use Case
|
|
68
|
+
|
|
69
|
+
An AI agency runs an automation for a client. The workflow touches models, tools, local files, web sources, and human approvals. The agency needs to show what happened without handing over raw prompts, outputs, files, secrets, or private source URLs.
|
|
70
|
+
|
|
71
|
+
ProofPacket creates one shareable proof packet:
|
|
72
|
+
|
|
73
|
+
1. The automation runs.
|
|
74
|
+
2. The SDK records bucketed events and hashes sensitive content.
|
|
75
|
+
3. A Markdown proof packet is generated for the client.
|
|
76
|
+
4. The client can verify the packet hash chain locally.
|
|
77
|
+
|
|
78
|
+
That is the wedge: a client-facing proof packet for AI work.
|
|
79
|
+
|
|
80
|
+
## When Should I Use ProofPacket?
|
|
81
|
+
|
|
82
|
+
Use ProofPacket when you are building an AI agent or LLM workflow and need a small evidence packet. Built-in wrappers currently cover Anthropic and OpenAI; other frameworks can use the SDK directly.
|
|
83
|
+
|
|
84
|
+
ProofPacket is especially useful for AI agencies, consultants, and developers who need to show what an AI workflow did without sharing the raw work.
|
|
85
|
+
|
|
86
|
+
## Install
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install proofpacket
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For local development:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install -e ".[dev]"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 60-Second Quickstart
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from proofpacket import Packet
|
|
102
|
+
|
|
103
|
+
packet = Packet(task="vendor_risk_review", actor="ai_agent")
|
|
104
|
+
|
|
105
|
+
with packet.llm_call(
|
|
106
|
+
provider="anthropic",
|
|
107
|
+
model="claude-4.5-sonnet",
|
|
108
|
+
bucket="summary_or_reasoning",
|
|
109
|
+
) as call:
|
|
110
|
+
call.record_input("Summarize vendor privacy policy.")
|
|
111
|
+
call.record_output("Vendor appears to retain customer data...")
|
|
112
|
+
|
|
113
|
+
packet.tool_call(
|
|
114
|
+
tool="browser.search",
|
|
115
|
+
bucket="web_research",
|
|
116
|
+
target="vendor privacy policy",
|
|
117
|
+
result_summary="Found vendor privacy policy and terms.",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
packet.human_review(
|
|
121
|
+
reviewer="user",
|
|
122
|
+
decision="approved",
|
|
123
|
+
note="Reviewed before sharing with client.",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
packet.finish(status="completed")
|
|
127
|
+
packet.export_json("proofpacket.json")
|
|
128
|
+
packet.export_markdown("proofpacket.md")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Working Provider Wrappers
|
|
132
|
+
|
|
133
|
+
Use a wrapper when you want ProofPacket to log provider calls automatically.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install "proofpacket[anthropic,openai]"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Anthropic
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from anthropic import Anthropic
|
|
143
|
+
from proofpacket import Packet
|
|
144
|
+
from proofpacket.wrappers.anthropic import wrap_client
|
|
145
|
+
|
|
146
|
+
packet = Packet(task="client_research", actor="ai_agent")
|
|
147
|
+
client = wrap_client(Anthropic(), receipt=packet, bucket="vendor_policy_review")
|
|
148
|
+
|
|
149
|
+
response = client.messages.create(
|
|
150
|
+
model="claude-4.5-sonnet",
|
|
151
|
+
max_tokens=300,
|
|
152
|
+
messages=[{"role": "user", "content": "Summarize this vendor policy."}],
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
packet.finish(status="completed")
|
|
156
|
+
packet.export_markdown("client_proof_packet.md")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### OpenAI
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from openai import OpenAI
|
|
163
|
+
from proofpacket import Packet
|
|
164
|
+
from proofpacket.wrappers.openai import wrap_client
|
|
165
|
+
|
|
166
|
+
packet = Packet(task="client_research", actor="ai_agent")
|
|
167
|
+
client = wrap_client(OpenAI(), receipt=packet, bucket="vendor_policy_review")
|
|
168
|
+
|
|
169
|
+
response = client.chat.completions.create(
|
|
170
|
+
model="gpt-4.1",
|
|
171
|
+
messages=[{"role": "user", "content": "Summarize this vendor policy."}],
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
packet.finish(status="completed")
|
|
175
|
+
packet.export_markdown("client_proof_packet.md")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The OpenAI wrapper currently targets Chat Completions. Responses API support is planned.
|
|
179
|
+
|
|
180
|
+
The wrappers record provider, model, input hash, output hash, token counts when available, timestamp, and event hash. They do not store raw prompts or outputs unless you explicitly use `privacy_mode="raw_capture"` and `raw_capture=True`.
|
|
181
|
+
|
|
182
|
+
You can override the event bucket on an individual call with `proofpacket_bucket="summary"`; the wrapper removes that helper argument before delegating to the provider.
|
|
183
|
+
|
|
184
|
+
## CLI
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
proofpacket init
|
|
188
|
+
proofpacket validate proofpacket.json
|
|
189
|
+
proofpacket verify proofpacket.json
|
|
190
|
+
proofpacket summarize proofpacket.json
|
|
191
|
+
proofpacket export proofpacket.json --markdown proofpacket.md
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`export` refuses invalid packets unless you pass `--force`.
|
|
195
|
+
|
|
196
|
+
## Privacy-Safe By Default
|
|
197
|
+
|
|
198
|
+
By default, `record_input` and `record_output` store SHA-256 hashes and character counts, not raw text.
|
|
199
|
+
|
|
200
|
+
Local file paths, filenames, tool targets, and source URIs are hashed or omitted by default. Caller-supplied notes, summaries, labels, and metadata strings pass through basic redaction and truncation.
|
|
201
|
+
|
|
202
|
+
`privacy_mode` is enforced:
|
|
203
|
+
|
|
204
|
+
- `hash_only` rejects previews and raw capture.
|
|
205
|
+
- `preview` permits redacted previews.
|
|
206
|
+
- `raw_capture` is required before raw LLM content can be stored.
|
|
207
|
+
|
|
208
|
+
The redaction helpers are convenience utilities, not a substitute for a DLP system.
|
|
209
|
+
|
|
210
|
+
## Trust Model
|
|
211
|
+
|
|
212
|
+
ProofPacket v0.1 packets are self-attested with integrity protection.
|
|
213
|
+
|
|
214
|
+
The hash chain can show that a packet changed after it was written. It cannot prove that the packet captured every action or that every event was categorized honestly.
|
|
215
|
+
|
|
216
|
+
Hashes are integrity anchors, not the whole audit story. A SHA-256 hash of an input or file is strongest when the original evidence is retained somewhere else and can be compared later.
|
|
217
|
+
|
|
218
|
+
The `attested_by` field records who or what created the packet. Future Trust Anchor deployments may support signed events from MCP hosts, provider wrappers, sandboxed runtimes, or human reviewers.
|
|
219
|
+
|
|
220
|
+
See [docs/trust_anchor.md](docs/trust_anchor.md).
|
|
221
|
+
|
|
222
|
+
## What ProofPacket Is Not
|
|
223
|
+
|
|
224
|
+
ProofPacket is not a hosted service. It produces a local file. There is no account to create and no data sent to a third party.
|
|
225
|
+
|
|
226
|
+
ProofPacket is not an observability platform, agent runtime, sandbox, policy engine, or legal compliance product. It is a minimal audit envelope that can sit beside those tools.
|
|
227
|
+
|
|
228
|
+
It is designed to support auditability and compliance workflows, but it does not claim SOC 2, HIPAA, ISO 42001, GDPR, or other certification.
|
|
229
|
+
|
|
230
|
+
## How It Fits
|
|
231
|
+
|
|
232
|
+
ProofPacket complements observability tools such as LangSmith, Langfuse, Helicone, and OpenTelemetry. It is narrower: a client-safe evidence packet rather than a full trace.
|
|
233
|
+
|
|
234
|
+
Hosted audit-trail services store events on their infrastructure. ProofPacket produces a local file, with optional Sigstore Rekor anchoring on the roadmap.
|
|
235
|
+
|
|
236
|
+
See [docs/comparison.md](docs/comparison.md).
|
|
237
|
+
|
|
238
|
+
## Schema And Hashes
|
|
239
|
+
|
|
240
|
+
Proof packets use deterministic JSON canonicalization, event hashes, previous-event hashes, and a final packet hash.
|
|
241
|
+
|
|
242
|
+
ProofPacket v0.1 pins its Python JSON serialization rules in [docs/canonicalization.md](docs/canonicalization.md). This is deterministic for packets emitted by the Python SDK, but it is not yet a full RFC 8785 implementation. Cross-language verification should be treated as experimental until a future schema version moves to JCS or a matching TypeScript profile.
|
|
243
|
+
|
|
244
|
+
## Project Status
|
|
245
|
+
|
|
246
|
+
ProofPacket is pre-1.0. Expect breaking schema changes before v1.0.
|
|
247
|
+
|
|
248
|
+
The project should stay small: evidence packets first, wrappers second, hosted storage later.
|
|
249
|
+
|
|
250
|
+
## Roadmap
|
|
251
|
+
|
|
252
|
+
Near term:
|
|
253
|
+
|
|
254
|
+
- LangChain callback handler
|
|
255
|
+
- MCP tool wrapper
|
|
256
|
+
- Ed25519 self-signing
|
|
257
|
+
- RFC 8785/JCS canonicalization decision
|
|
258
|
+
|
|
259
|
+
Later:
|
|
260
|
+
|
|
261
|
+
- TypeScript SDK
|
|
262
|
+
- PDF export
|
|
263
|
+
- OpenTelemetry exporter
|
|
264
|
+
- GitHub Action for AI-generated PR evidence
|
|
265
|
+
- Hosted Evidence Locker
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/proofpacket-logo.png" alt="ProofPacket logo" width="160">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# ProofPacket
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Your AI agent did 47 things. Send your client one proof packet.
|
|
12
|
+
|
|
13
|
+
Local-first. No SaaS account. ProofPacket does not send your packet data to a ProofPacket service.
|
|
14
|
+
|
|
15
|
+
ProofPacket is an open-source Python SDK and JSON schema for privacy-safe evidence packets for AI agent runs and LLM workflows.
|
|
16
|
+
|
|
17
|
+
Use ProofPacket when you need an AI agent audit trail, LLM audit log, AI automation evidence packet, or client-facing proof of what an AI workflow did without storing raw prompts, outputs, files, source URLs, local paths, or secrets.
|
|
18
|
+
|
|
19
|
+
ProofPacket records LLM calls, tool calls, file access, human approvals, sources, risk flags, and hash-chain verification as a shareable evidence packet.
|
|
20
|
+
|
|
21
|
+
v0.1 includes thin wrappers for Anthropic `messages.create(...)` and OpenAI `chat.completions.create(...)`. Other Python LLM workflows can use the SDK directly. LangChain, MCP, and Claude Code integrations are planned.
|
|
22
|
+
|
|
23
|
+
No raw prompts. No file contents. No leaked source URLs or local paths by default. Verifiable.
|
|
24
|
+
|
|
25
|
+
Provider wrappers still call the configured LLM provider. ProofPacket keeps the JSON/Markdown evidence packet local unless you choose to share it.
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
$ proofpacket verify examples/sample_packet.json
|
|
31
|
+
valid
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## The Flagship Use Case
|
|
35
|
+
|
|
36
|
+
An AI agency runs an automation for a client. The workflow touches models, tools, local files, web sources, and human approvals. The agency needs to show what happened without handing over raw prompts, outputs, files, secrets, or private source URLs.
|
|
37
|
+
|
|
38
|
+
ProofPacket creates one shareable proof packet:
|
|
39
|
+
|
|
40
|
+
1. The automation runs.
|
|
41
|
+
2. The SDK records bucketed events and hashes sensitive content.
|
|
42
|
+
3. A Markdown proof packet is generated for the client.
|
|
43
|
+
4. The client can verify the packet hash chain locally.
|
|
44
|
+
|
|
45
|
+
That is the wedge: a client-facing proof packet for AI work.
|
|
46
|
+
|
|
47
|
+
## When Should I Use ProofPacket?
|
|
48
|
+
|
|
49
|
+
Use ProofPacket when you are building an AI agent or LLM workflow and need a small evidence packet. Built-in wrappers currently cover Anthropic and OpenAI; other frameworks can use the SDK directly.
|
|
50
|
+
|
|
51
|
+
ProofPacket is especially useful for AI agencies, consultants, and developers who need to show what an AI workflow did without sharing the raw work.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install proofpacket
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For local development:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 60-Second Quickstart
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from proofpacket import Packet
|
|
69
|
+
|
|
70
|
+
packet = Packet(task="vendor_risk_review", actor="ai_agent")
|
|
71
|
+
|
|
72
|
+
with packet.llm_call(
|
|
73
|
+
provider="anthropic",
|
|
74
|
+
model="claude-4.5-sonnet",
|
|
75
|
+
bucket="summary_or_reasoning",
|
|
76
|
+
) as call:
|
|
77
|
+
call.record_input("Summarize vendor privacy policy.")
|
|
78
|
+
call.record_output("Vendor appears to retain customer data...")
|
|
79
|
+
|
|
80
|
+
packet.tool_call(
|
|
81
|
+
tool="browser.search",
|
|
82
|
+
bucket="web_research",
|
|
83
|
+
target="vendor privacy policy",
|
|
84
|
+
result_summary="Found vendor privacy policy and terms.",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
packet.human_review(
|
|
88
|
+
reviewer="user",
|
|
89
|
+
decision="approved",
|
|
90
|
+
note="Reviewed before sharing with client.",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
packet.finish(status="completed")
|
|
94
|
+
packet.export_json("proofpacket.json")
|
|
95
|
+
packet.export_markdown("proofpacket.md")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Working Provider Wrappers
|
|
99
|
+
|
|
100
|
+
Use a wrapper when you want ProofPacket to log provider calls automatically.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install "proofpacket[anthropic,openai]"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Anthropic
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from anthropic import Anthropic
|
|
110
|
+
from proofpacket import Packet
|
|
111
|
+
from proofpacket.wrappers.anthropic import wrap_client
|
|
112
|
+
|
|
113
|
+
packet = Packet(task="client_research", actor="ai_agent")
|
|
114
|
+
client = wrap_client(Anthropic(), receipt=packet, bucket="vendor_policy_review")
|
|
115
|
+
|
|
116
|
+
response = client.messages.create(
|
|
117
|
+
model="claude-4.5-sonnet",
|
|
118
|
+
max_tokens=300,
|
|
119
|
+
messages=[{"role": "user", "content": "Summarize this vendor policy."}],
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
packet.finish(status="completed")
|
|
123
|
+
packet.export_markdown("client_proof_packet.md")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### OpenAI
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from openai import OpenAI
|
|
130
|
+
from proofpacket import Packet
|
|
131
|
+
from proofpacket.wrappers.openai import wrap_client
|
|
132
|
+
|
|
133
|
+
packet = Packet(task="client_research", actor="ai_agent")
|
|
134
|
+
client = wrap_client(OpenAI(), receipt=packet, bucket="vendor_policy_review")
|
|
135
|
+
|
|
136
|
+
response = client.chat.completions.create(
|
|
137
|
+
model="gpt-4.1",
|
|
138
|
+
messages=[{"role": "user", "content": "Summarize this vendor policy."}],
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
packet.finish(status="completed")
|
|
142
|
+
packet.export_markdown("client_proof_packet.md")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The OpenAI wrapper currently targets Chat Completions. Responses API support is planned.
|
|
146
|
+
|
|
147
|
+
The wrappers record provider, model, input hash, output hash, token counts when available, timestamp, and event hash. They do not store raw prompts or outputs unless you explicitly use `privacy_mode="raw_capture"` and `raw_capture=True`.
|
|
148
|
+
|
|
149
|
+
You can override the event bucket on an individual call with `proofpacket_bucket="summary"`; the wrapper removes that helper argument before delegating to the provider.
|
|
150
|
+
|
|
151
|
+
## CLI
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
proofpacket init
|
|
155
|
+
proofpacket validate proofpacket.json
|
|
156
|
+
proofpacket verify proofpacket.json
|
|
157
|
+
proofpacket summarize proofpacket.json
|
|
158
|
+
proofpacket export proofpacket.json --markdown proofpacket.md
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`export` refuses invalid packets unless you pass `--force`.
|
|
162
|
+
|
|
163
|
+
## Privacy-Safe By Default
|
|
164
|
+
|
|
165
|
+
By default, `record_input` and `record_output` store SHA-256 hashes and character counts, not raw text.
|
|
166
|
+
|
|
167
|
+
Local file paths, filenames, tool targets, and source URIs are hashed or omitted by default. Caller-supplied notes, summaries, labels, and metadata strings pass through basic redaction and truncation.
|
|
168
|
+
|
|
169
|
+
`privacy_mode` is enforced:
|
|
170
|
+
|
|
171
|
+
- `hash_only` rejects previews and raw capture.
|
|
172
|
+
- `preview` permits redacted previews.
|
|
173
|
+
- `raw_capture` is required before raw LLM content can be stored.
|
|
174
|
+
|
|
175
|
+
The redaction helpers are convenience utilities, not a substitute for a DLP system.
|
|
176
|
+
|
|
177
|
+
## Trust Model
|
|
178
|
+
|
|
179
|
+
ProofPacket v0.1 packets are self-attested with integrity protection.
|
|
180
|
+
|
|
181
|
+
The hash chain can show that a packet changed after it was written. It cannot prove that the packet captured every action or that every event was categorized honestly.
|
|
182
|
+
|
|
183
|
+
Hashes are integrity anchors, not the whole audit story. A SHA-256 hash of an input or file is strongest when the original evidence is retained somewhere else and can be compared later.
|
|
184
|
+
|
|
185
|
+
The `attested_by` field records who or what created the packet. Future Trust Anchor deployments may support signed events from MCP hosts, provider wrappers, sandboxed runtimes, or human reviewers.
|
|
186
|
+
|
|
187
|
+
See [docs/trust_anchor.md](docs/trust_anchor.md).
|
|
188
|
+
|
|
189
|
+
## What ProofPacket Is Not
|
|
190
|
+
|
|
191
|
+
ProofPacket is not a hosted service. It produces a local file. There is no account to create and no data sent to a third party.
|
|
192
|
+
|
|
193
|
+
ProofPacket is not an observability platform, agent runtime, sandbox, policy engine, or legal compliance product. It is a minimal audit envelope that can sit beside those tools.
|
|
194
|
+
|
|
195
|
+
It is designed to support auditability and compliance workflows, but it does not claim SOC 2, HIPAA, ISO 42001, GDPR, or other certification.
|
|
196
|
+
|
|
197
|
+
## How It Fits
|
|
198
|
+
|
|
199
|
+
ProofPacket complements observability tools such as LangSmith, Langfuse, Helicone, and OpenTelemetry. It is narrower: a client-safe evidence packet rather than a full trace.
|
|
200
|
+
|
|
201
|
+
Hosted audit-trail services store events on their infrastructure. ProofPacket produces a local file, with optional Sigstore Rekor anchoring on the roadmap.
|
|
202
|
+
|
|
203
|
+
See [docs/comparison.md](docs/comparison.md).
|
|
204
|
+
|
|
205
|
+
## Schema And Hashes
|
|
206
|
+
|
|
207
|
+
Proof packets use deterministic JSON canonicalization, event hashes, previous-event hashes, and a final packet hash.
|
|
208
|
+
|
|
209
|
+
ProofPacket v0.1 pins its Python JSON serialization rules in [docs/canonicalization.md](docs/canonicalization.md). This is deterministic for packets emitted by the Python SDK, but it is not yet a full RFC 8785 implementation. Cross-language verification should be treated as experimental until a future schema version moves to JCS or a matching TypeScript profile.
|
|
210
|
+
|
|
211
|
+
## Project Status
|
|
212
|
+
|
|
213
|
+
ProofPacket is pre-1.0. Expect breaking schema changes before v1.0.
|
|
214
|
+
|
|
215
|
+
The project should stay small: evidence packets first, wrappers second, hosted storage later.
|
|
216
|
+
|
|
217
|
+
## Roadmap
|
|
218
|
+
|
|
219
|
+
Near term:
|
|
220
|
+
|
|
221
|
+
- LangChain callback handler
|
|
222
|
+
- MCP tool wrapper
|
|
223
|
+
- Ed25519 self-signing
|
|
224
|
+
- RFC 8785/JCS canonicalization decision
|
|
225
|
+
|
|
226
|
+
Later:
|
|
227
|
+
|
|
228
|
+
- TypeScript SDK
|
|
229
|
+
- PDF export
|
|
230
|
+
- OpenTelemetry exporter
|
|
231
|
+
- GitHub Action for AI-generated PR evidence
|
|
232
|
+
- Hosted Evidence Locker
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""ProofPacket: privacy-safe evidence packets for AI agent runs."""
|
|
2
|
+
|
|
3
|
+
from proofpacket.hashing import VerificationResult, verify_receipt
|
|
4
|
+
from proofpacket.receipt import Receipt
|
|
5
|
+
|
|
6
|
+
Packet = Receipt
|
|
7
|
+
|
|
8
|
+
__all__ = ["Packet", "Receipt", "VerificationResult", "verify_receipt"]
|
|
9
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Command line interface for ProofPacket."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from proofpacket.exporters import export_markdown
|
|
12
|
+
from proofpacket.hashing import verify_receipt
|
|
13
|
+
from proofpacket.receipt import Receipt
|
|
14
|
+
from proofpacket.schema import load_schema
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(help="Create, validate, verify, summarize, and export ProofPacket evidence packets.")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _load_receipt(path: Path) -> dict:
|
|
20
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.command()
|
|
24
|
+
def init(directory: Path = typer.Argument(Path("."), help="Directory to initialize.")) -> None:
|
|
25
|
+
"""Create a minimal local ProofPacket policy and template packet."""
|
|
26
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
27
|
+
config_path = directory / "proofpacket.config.json"
|
|
28
|
+
template_path = directory / "proofpacket-template.json"
|
|
29
|
+
config_path.write_text(
|
|
30
|
+
json.dumps(
|
|
31
|
+
{
|
|
32
|
+
"privacy_mode": "hash_only",
|
|
33
|
+
"raw_capture_default": False,
|
|
34
|
+
"require_human_review_for_external_actions": True,
|
|
35
|
+
},
|
|
36
|
+
indent=2,
|
|
37
|
+
)
|
|
38
|
+
+ "\n",
|
|
39
|
+
encoding="utf-8",
|
|
40
|
+
)
|
|
41
|
+
receipt = Receipt(task="example_task", actor="ai_agent")
|
|
42
|
+
receipt.note("Template packet initialized.")
|
|
43
|
+
receipt.finish(status="completed")
|
|
44
|
+
receipt.export_json(template_path)
|
|
45
|
+
typer.echo(f"Created {config_path}")
|
|
46
|
+
typer.echo(f"Created {template_path}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@app.command()
|
|
50
|
+
def validate(receipt_path: Path) -> None:
|
|
51
|
+
"""Validate a packet against the JSON schema."""
|
|
52
|
+
try:
|
|
53
|
+
from jsonschema import validate as jsonschema_validate
|
|
54
|
+
except ImportError as exc: # pragma: no cover
|
|
55
|
+
raise typer.Exit(f"jsonschema is required for validation: {exc}")
|
|
56
|
+
|
|
57
|
+
receipt = _load_receipt(receipt_path)
|
|
58
|
+
jsonschema_validate(instance=receipt, schema=load_schema())
|
|
59
|
+
typer.echo("valid")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@app.command()
|
|
63
|
+
def verify(receipt_path: Path) -> None:
|
|
64
|
+
"""Verify hash chain and packet hash."""
|
|
65
|
+
result = verify_receipt(_load_receipt(receipt_path))
|
|
66
|
+
if result.valid:
|
|
67
|
+
typer.echo("valid")
|
|
68
|
+
return
|
|
69
|
+
typer.echo("invalid")
|
|
70
|
+
for error in result.errors:
|
|
71
|
+
typer.echo(f"- {error}")
|
|
72
|
+
raise typer.Exit(1)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@app.command()
|
|
76
|
+
def summarize(receipt_path: Path) -> None:
|
|
77
|
+
"""Print a human-readable packet summary."""
|
|
78
|
+
receipt = _load_receipt(receipt_path)
|
|
79
|
+
events = receipt.get("events", [])
|
|
80
|
+
providers = sorted(
|
|
81
|
+
{
|
|
82
|
+
event.get("metadata", {}).get("provider")
|
|
83
|
+
for event in events
|
|
84
|
+
if event.get("event_type") == "llm_call" and event.get("metadata", {}).get("provider")
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
tools = sorted(
|
|
88
|
+
{
|
|
89
|
+
event.get("metadata", {}).get("tool")
|
|
90
|
+
for event in events
|
|
91
|
+
if event.get("event_type") == "tool_call" and event.get("metadata", {}).get("tool")
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
source_buckets = sorted({event.get("bucket") for event in events if event.get("event_type") == "source_used"})
|
|
95
|
+
reviews = [event for event in events if event.get("event_type") == "human_review"]
|
|
96
|
+
typer.echo(f"Task: {receipt.get('task')}")
|
|
97
|
+
typer.echo(f"Status: {receipt.get('status')}")
|
|
98
|
+
typer.echo(f"Started: {receipt.get('started_at')}")
|
|
99
|
+
typer.echo(f"Finished: {receipt.get('finished_at')}")
|
|
100
|
+
typer.echo(f"Events: {len(events)}")
|
|
101
|
+
typer.echo(f"Model providers: {', '.join(providers) if providers else 'none'}")
|
|
102
|
+
typer.echo(f"Tools: {', '.join(tools) if tools else 'none'}")
|
|
103
|
+
typer.echo(f"Source buckets: {', '.join(source_buckets) if source_buckets else 'none'}")
|
|
104
|
+
typer.echo(f"Human reviews: {len(reviews)}")
|
|
105
|
+
typer.echo(f"Risk flags: {len(receipt.get('risk_flags', []))}")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@app.command()
|
|
109
|
+
def export(
|
|
110
|
+
receipt_path: Path,
|
|
111
|
+
markdown: Optional[Path] = typer.Option(None, "--markdown", "-m"),
|
|
112
|
+
force: bool = typer.Option(False, "--force", help="Export even if verification fails."),
|
|
113
|
+
) -> None:
|
|
114
|
+
"""Export a packet to another format."""
|
|
115
|
+
if markdown is None:
|
|
116
|
+
raise typer.BadParameter("Only --markdown is supported in v0.1.")
|
|
117
|
+
receipt = _load_receipt(receipt_path)
|
|
118
|
+
result = verify_receipt(receipt)
|
|
119
|
+
if not result.valid and not force:
|
|
120
|
+
typer.echo("Packet verification failed; use --force to export anyway.")
|
|
121
|
+
for error in result.errors:
|
|
122
|
+
typer.echo(f"- {error}")
|
|
123
|
+
raise typer.Exit(1)
|
|
124
|
+
export_markdown(receipt, markdown)
|
|
125
|
+
typer.echo(f"Created {markdown}")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
if __name__ == "__main__":
|
|
129
|
+
app()
|