remembr-proof 0.3.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.
- remembr_proof-0.3.0/PKG-INFO +361 -0
- remembr_proof-0.3.0/README.md +340 -0
- remembr_proof-0.3.0/pyproject.toml +34 -0
- remembr_proof-0.3.0/remembr_proof/__init__.py +116 -0
- remembr_proof-0.3.0/remembr_proof/agents.py +262 -0
- remembr_proof-0.3.0/remembr_proof/automation.py +348 -0
- remembr_proof-0.3.0/remembr_proof/client.py +565 -0
- remembr_proof-0.3.0/remembr_proof/computer.py +344 -0
- remembr_proof-0.3.0/remembr_proof/logging.py +83 -0
- remembr_proof-0.3.0/remembr_proof/middleware.py +247 -0
- remembr_proof-0.3.0/remembr_proof/onyx.py +371 -0
- remembr_proof-0.3.0/remembr_proof/orchestrator.py +260 -0
- remembr_proof-0.3.0/remembr_proof/perplexity.py +373 -0
- remembr_proof-0.3.0/remembr_proof/remembr.py +411 -0
- remembr_proof-0.3.0/remembr_proof/selfdialogue.py +292 -0
- remembr_proof-0.3.0/remembr_proof/synthesis.py +354 -0
- remembr_proof-0.3.0/remembr_proof/upgrade.py +148 -0
- remembr_proof-0.3.0/remembr_proof/watchdog.py +235 -0
- remembr_proof-0.3.0/remembr_proof.egg-info/PKG-INFO +361 -0
- remembr_proof-0.3.0/remembr_proof.egg-info/SOURCES.txt +30 -0
- remembr_proof-0.3.0/remembr_proof.egg-info/dependency_links.txt +1 -0
- remembr_proof-0.3.0/remembr_proof.egg-info/requires.txt +3 -0
- remembr_proof-0.3.0/remembr_proof.egg-info/top_level.txt +1 -0
- remembr_proof-0.3.0/setup.cfg +4 -0
- remembr_proof-0.3.0/tests/test_agents_orchestrator_selfdialogue.py +777 -0
- remembr_proof-0.3.0/tests/test_automation.py +450 -0
- remembr_proof-0.3.0/tests/test_client.py +1376 -0
- remembr_proof-0.3.0/tests/test_onyx.py +376 -0
- remembr_proof-0.3.0/tests/test_perplexity_computer.py +520 -0
- remembr_proof-0.3.0/tests/test_remembr.py +456 -0
- remembr_proof-0.3.0/tests/test_upgrade.py +211 -0
- remembr_proof-0.3.0/tests/test_watchdog.py +277 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: remembr-proof
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Python SDK for the REMEMBR Proof Seal API — verify AI reasoning chains
|
|
5
|
+
Author-email: REMEMBR Council <hello@remembrrr.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://remembrrr.ai
|
|
8
|
+
Keywords: ai,verification,proof,reasoning,llm,safety,audit
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Provides-Extra: agents
|
|
20
|
+
Requires-Dist: openai-agents; extra == "agents"
|
|
21
|
+
|
|
22
|
+
# remembr-proof
|
|
23
|
+
|
|
24
|
+
Python SDK for the REMEMBR Proof Seal API.
|
|
25
|
+
|
|
26
|
+
Verify AI outputs against any visible supporting trace, detect contradictions, and generate audit-ready certificates with a single function call.
|
|
27
|
+
|
|
28
|
+
For the HTTP-first walkthrough, see `../../docs/proof-seal-quickstart.md`.
|
|
29
|
+
For the canonical API acceptance boundary, see `../../PROOF_SEAL_API_CONTRACT.md`.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install remembr-proof
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from remembr_proof import ProofSeal
|
|
41
|
+
|
|
42
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
43
|
+
|
|
44
|
+
cert = seal.verify(
|
|
45
|
+
output="Employees must complete security awareness training every year.",
|
|
46
|
+
task_type="policy",
|
|
47
|
+
retrieved_context=[
|
|
48
|
+
{
|
|
49
|
+
"id": "policy-7.2",
|
|
50
|
+
"title": "Security Awareness Policy",
|
|
51
|
+
"content": "All employees must complete security awareness training annually.",
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
citations=[
|
|
55
|
+
{
|
|
56
|
+
"source_id": "policy-7.2",
|
|
57
|
+
"quote": "All employees must complete security awareness training annually.",
|
|
58
|
+
"claim": "Training is required every year",
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
print(cert.verdict) # "verified"
|
|
64
|
+
print(cert.confidence) # 0.92
|
|
65
|
+
print(cert.support.support_score) # 1.0
|
|
66
|
+
print(cert.contradictions) # []
|
|
67
|
+
|
|
68
|
+
# Output-only calls are accepted, but the SDK does not pretend certainty
|
|
69
|
+
# when no visible trace is supplied.
|
|
70
|
+
output_only = seal.verify(
|
|
71
|
+
output="Employees must complete security awareness training every year.",
|
|
72
|
+
task_type="policy",
|
|
73
|
+
)
|
|
74
|
+
print(output_only.verdict) # "insufficient_evidence"
|
|
75
|
+
print(output_only.insufficient_evidence_reasons) # ["missing_visible_support"]
|
|
76
|
+
|
|
77
|
+
# Optional: request the shadow extractor report for comparison/debugging
|
|
78
|
+
shadow_cert = seal.verify(
|
|
79
|
+
output="Employees must complete security awareness training every year.",
|
|
80
|
+
task_type="policy",
|
|
81
|
+
reasoning_steps=[
|
|
82
|
+
{
|
|
83
|
+
"role": "assistant",
|
|
84
|
+
"content": "Security policy requires annual training.",
|
|
85
|
+
"claims": ["Training is annual"],
|
|
86
|
+
"evidence": ["Policy 7.2"],
|
|
87
|
+
"confidence": 0.9,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
shadow_extraction=True,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
print(shadow_cert.shadow_extractor_status) # "success" | "skipped" | "error"
|
|
94
|
+
if shadow_cert.shadow_reasoning_integrity:
|
|
95
|
+
print(shadow_cert.shadow_reasoning_integrity.integrity_score)
|
|
96
|
+
if shadow_cert.shadow_extractor_error:
|
|
97
|
+
print(shadow_cert.shadow_extractor_error)
|
|
98
|
+
|
|
99
|
+
# Check usage
|
|
100
|
+
usage = seal.get_usage()
|
|
101
|
+
print(f"Today: {usage.today_count}/{usage.daily_limit}")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
API keys use the `rp_` family of prefixes. Self-serve trial keys use
|
|
105
|
+
`rp_free_`, paid pilot keys use `rp_live_`, and founder keys use
|
|
106
|
+
`rp_founder_`.
|
|
107
|
+
|
|
108
|
+
## Policy And Shadow Extraction
|
|
109
|
+
|
|
110
|
+
`reasoning_steps` is optional, but stronger verdicts require visible support.
|
|
111
|
+
If you only send the final output, Proof Seal will usually return
|
|
112
|
+
`insufficient_evidence` instead of a strong verification verdict.
|
|
113
|
+
|
|
114
|
+
For high-trust task types such as `policy`, `legal_internal`, and
|
|
115
|
+
`finance_ops`, `verified` is stricter than a generic confidence label. In
|
|
116
|
+
those workflows, Proof Seal will not return `verified` if unresolved
|
|
117
|
+
unsupported claims remain after visible-evidence reconciliation.
|
|
118
|
+
|
|
119
|
+
When a request resolves to `insufficient_evidence`, the certificate also
|
|
120
|
+
includes machine-readable `insufficient_evidence_reasons`. The SDK exports the
|
|
121
|
+
canonical taxonomy as `INSUFFICIENT_EVIDENCE_REASONS` plus
|
|
122
|
+
`is_insufficient_evidence_reason()` so callers can branch on stable reason IDs
|
|
123
|
+
instead of ad-hoc strings:
|
|
124
|
+
|
|
125
|
+
- `missing_visible_support`
|
|
126
|
+
- `weak_support_present`
|
|
127
|
+
- `unsupported_claims_present`
|
|
128
|
+
- `missing_grounded_citations`
|
|
129
|
+
- `missing_successful_tool_call`
|
|
130
|
+
|
|
131
|
+
When a request resolves to `policy_rejected`, the certificate also includes
|
|
132
|
+
machine-readable `policy_rejection_reasons`. The SDK exports the canonical
|
|
133
|
+
taxonomy as `POLICY_REJECTION_REASONS` plus `is_policy_rejection_reason()`:
|
|
134
|
+
|
|
135
|
+
- `integrity_below_minimum`
|
|
136
|
+
- `support_below_minimum`
|
|
137
|
+
- `contradictions_present`
|
|
138
|
+
- `unsupported_claims_present`
|
|
139
|
+
- `missing_required_grounded_citations`
|
|
140
|
+
- `missing_required_successful_tool_call`
|
|
141
|
+
- `unsafe_content_detected`
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from remembr_proof import (
|
|
145
|
+
INSUFFICIENT_EVIDENCE_REASONS,
|
|
146
|
+
POLICY_REJECTION_REASONS,
|
|
147
|
+
ProofSeal,
|
|
148
|
+
is_insufficient_evidence_reason,
|
|
149
|
+
is_policy_rejection_reason,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
cert = seal.verify(
|
|
153
|
+
output="Critical decision output.",
|
|
154
|
+
task_type="policy",
|
|
155
|
+
retrieved_context=[
|
|
156
|
+
{"id": "policy-7.2", "content": "All employees must complete security awareness training annually."},
|
|
157
|
+
],
|
|
158
|
+
citations=[
|
|
159
|
+
{"source_id": "policy-7.2", "quote": "All employees must complete security awareness training annually."},
|
|
160
|
+
],
|
|
161
|
+
policy={
|
|
162
|
+
"min_support_score": 0.75,
|
|
163
|
+
"require_grounded_citations": True,
|
|
164
|
+
},
|
|
165
|
+
shadow_extraction=True,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
print(cert.is_policy_rejected)
|
|
169
|
+
print(cert.policy_violations)
|
|
170
|
+
print(POLICY_REJECTION_REASONS)
|
|
171
|
+
print(cert.shadow_extractor_status)
|
|
172
|
+
print(INSUFFICIENT_EVIDENCE_REASONS)
|
|
173
|
+
|
|
174
|
+
for reason in cert.policy_rejection_reasons:
|
|
175
|
+
assert is_policy_rejection_reason(reason)
|
|
176
|
+
|
|
177
|
+
for reason in cert.insufficient_evidence_reasons:
|
|
178
|
+
assert is_insufficient_evidence_reason(reason)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Middleware (OpenAI / Anthropic)
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from openai import OpenAI
|
|
185
|
+
from remembr_proof import with_proof_seal
|
|
186
|
+
|
|
187
|
+
client = with_proof_seal(OpenAI(), api_key="rp_live_YOUR_KEY")
|
|
188
|
+
|
|
189
|
+
response = client.chat.completions.create(
|
|
190
|
+
model="gpt-5.5",
|
|
191
|
+
messages=[{"role": "user", "content": "Summarize the quarterly numbers."}],
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
print(response.proof_certificate.verdict)
|
|
195
|
+
print(response.proof_certificate.confidence)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## OpenAI Agents SDK
|
|
199
|
+
|
|
200
|
+
Install the optional agent dependency:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pip install "remembr-proof[agents]"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Wrap an OpenAI Agents SDK agent to verify the final output and visible run trace before your application trusts the result:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from agents import Agent, function_tool
|
|
210
|
+
from remembr_proof import ProofSeal, VerifiedAgent
|
|
211
|
+
|
|
212
|
+
@function_tool
|
|
213
|
+
def lookup_policy(query: str) -> str:
|
|
214
|
+
return "Security awareness training is annual."
|
|
215
|
+
|
|
216
|
+
agent = Agent(name="Policy researcher", tools=[lookup_policy])
|
|
217
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
218
|
+
verified_agent = VerifiedAgent(
|
|
219
|
+
agent,
|
|
220
|
+
seal,
|
|
221
|
+
task_type="policy",
|
|
222
|
+
policy={"min_support_score": 0.75, "require_successful_tool_call": True},
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
result = verified_agent.run_sync("Can employees skip annual security training?")
|
|
226
|
+
|
|
227
|
+
print(result.final_output)
|
|
228
|
+
print(result.certificate.verdict)
|
|
229
|
+
print(result.is_verified)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`VerifiedAgent` keeps `openai-agents` as a soft dependency. Importing `remembr_proof` does not require it; the dependency is required only when `VerifiedAgent.run()` or `VerifiedAgent.run_sync()` is called.
|
|
233
|
+
|
|
234
|
+
## Perplexity Pro Search
|
|
235
|
+
|
|
236
|
+
Use `PerplexityClient` for Sonar API research and `VerifiedSearch` to verify the answer plus returned citations before trusting it:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from remembr_proof import PerplexityClient, ProofSeal, VerifiedSearch
|
|
240
|
+
|
|
241
|
+
search = VerifiedSearch(
|
|
242
|
+
PerplexityClient(api_key="pplx_YOUR_KEY"),
|
|
243
|
+
ProofSeal(api_key="rp_live_YOUR_KEY"),
|
|
244
|
+
task_type="research",
|
|
245
|
+
policy={"require_grounded_citations": True, "reject_on_contradictions": True},
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
result = search.query("What changed in the market this week?")
|
|
249
|
+
print(result.answer)
|
|
250
|
+
print(result.verdict)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Perplexity output is external research, not proof. Store the returned Proof Seal certificate id and review unresolved contradictions before acting on the answer.
|
|
254
|
+
|
|
255
|
+
## Own Special Ability: Adversarial Synthesis
|
|
256
|
+
|
|
257
|
+
Use `AdversarialSynthesis` when you want REMEMBR to verify both a claim and its strongest challenge before reporting what survived:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
from remembr_proof import AdversarialSynthesis, ProofSeal
|
|
261
|
+
|
|
262
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
263
|
+
synthesis = AdversarialSynthesis(seal)
|
|
264
|
+
|
|
265
|
+
result = synthesis.run_sync(
|
|
266
|
+
claim="Enterprise AI spend will reach $297B by 2027.",
|
|
267
|
+
evidence=[{"id": "src-1", "content": "AI spending projected at $297B by 2027."}],
|
|
268
|
+
citations=[{"source_id": "src-1", "quote": "$297B by 2027", "claim": "$297B by 2027"}],
|
|
269
|
+
task_type="research",
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
print(result.synthesis_verdict)
|
|
273
|
+
print(result.refined_confidence)
|
|
274
|
+
print(result.crux)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
The public Worker packet for this ability is `GET /api/own-special-ability`; the admin advisory packet is `GET /api/admin/synthesis`.
|
|
278
|
+
|
|
279
|
+
## Real Client Use Cases
|
|
280
|
+
|
|
281
|
+
The repo includes concrete client workflow packets:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
python examples/created-features/client-real-life-use-cases.py --dry-run
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The dry run does not call the API. It shows the payloads for support QA, legal notice-period review, finance invoice checks, compliance policy answers, market research packets, and release notes gated on tool output.
|
|
288
|
+
|
|
289
|
+
Run live only after setting credentials and a base URL:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
REMEMBR_PROOF_API_KEY=rp_live_YOUR_KEY \
|
|
293
|
+
REMEMBR_PROOF_BASE_URL=http://127.0.0.1:8787 \
|
|
294
|
+
python examples/created-features/client-real-life-use-cases.py --live
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Computer Code Runner
|
|
298
|
+
|
|
299
|
+
Use `CodeRunner` for local subprocess execution and `VerifiedCodeRunner` when you want Proof Seal to verify captured output as a tool result:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
from remembr_proof import CodeRunner, ProofSeal, VerifiedCodeRunner
|
|
303
|
+
|
|
304
|
+
runner = VerifiedCodeRunner(
|
|
305
|
+
CodeRunner(timeout=10),
|
|
306
|
+
ProofSeal(api_key="rp_live_YOUR_KEY"),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
result = runner.run_python("print(2 + 2)")
|
|
310
|
+
print(result.stdout)
|
|
311
|
+
print(result.certificate.verdict if result.certificate else "unverified")
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`CodeRunner` is not a sandbox. Run untrusted code in a container or VM and do not grant it access to secrets or private data.
|
|
315
|
+
|
|
316
|
+
## Pricing
|
|
317
|
+
|
|
318
|
+
| Tier | Base | Per Verification | Daily Limit | Monthly Limit | Rate Limit |
|
|
319
|
+
|------|------|-----------------|-------------|---------------|------------|
|
|
320
|
+
| Free | $0/mo | $0 | 100 | 2,000 | 10/min |
|
|
321
|
+
| Pro | $49/mo | $0.005 | 10,000 | 300,000 | 60/min |
|
|
322
|
+
| Scale | $299/mo | $0.003 | 100,000 | 3,000,000 | 300/min |
|
|
323
|
+
| Enterprise | Custom | $0.001 | 1,000,000 | 30,000,000 | 1,000/min |
|
|
324
|
+
|
|
325
|
+
## Error Handling
|
|
326
|
+
|
|
327
|
+
All API errors raise `VerificationError`. The `status_code` attribute holds the HTTP status:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from remembr_proof import ProofSeal, VerificationError
|
|
331
|
+
|
|
332
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
333
|
+
|
|
334
|
+
try:
|
|
335
|
+
cert = seal.verify(output="...", task_type="policy")
|
|
336
|
+
except VerificationError as e:
|
|
337
|
+
if e.status_code == 401:
|
|
338
|
+
print("Invalid or revoked API key")
|
|
339
|
+
elif e.status_code == 429:
|
|
340
|
+
print("Rate limit or daily/monthly quota exceeded — back off and retry")
|
|
341
|
+
elif e.status_code == 400:
|
|
342
|
+
print(f"Bad request: {e}")
|
|
343
|
+
else:
|
|
344
|
+
print(f"API error {e.status_code}: {e}")
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Connection failures (DNS, timeout) also raise `VerificationError` with `status_code = 0`.
|
|
348
|
+
|
|
349
|
+
The SDK has no built-in retry logic. For production use, wrap calls with your own exponential backoff on `429` and `5xx` responses.
|
|
350
|
+
|
|
351
|
+
## Timeouts
|
|
352
|
+
|
|
353
|
+
The default request timeout is **30 seconds**. Override it at construction time:
|
|
354
|
+
|
|
355
|
+
```python
|
|
356
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY", timeout=60)
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Dependencies
|
|
360
|
+
|
|
361
|
+
The SDK uses the Python standard library only (`urllib`, `dataclasses`, `json`). No third-party packages are required.
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# remembr-proof
|
|
2
|
+
|
|
3
|
+
Python SDK for the REMEMBR Proof Seal API.
|
|
4
|
+
|
|
5
|
+
Verify AI outputs against any visible supporting trace, detect contradictions, and generate audit-ready certificates with a single function call.
|
|
6
|
+
|
|
7
|
+
For the HTTP-first walkthrough, see `../../docs/proof-seal-quickstart.md`.
|
|
8
|
+
For the canonical API acceptance boundary, see `../../PROOF_SEAL_API_CONTRACT.md`.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install remembr-proof
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from remembr_proof import ProofSeal
|
|
20
|
+
|
|
21
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
22
|
+
|
|
23
|
+
cert = seal.verify(
|
|
24
|
+
output="Employees must complete security awareness training every year.",
|
|
25
|
+
task_type="policy",
|
|
26
|
+
retrieved_context=[
|
|
27
|
+
{
|
|
28
|
+
"id": "policy-7.2",
|
|
29
|
+
"title": "Security Awareness Policy",
|
|
30
|
+
"content": "All employees must complete security awareness training annually.",
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
citations=[
|
|
34
|
+
{
|
|
35
|
+
"source_id": "policy-7.2",
|
|
36
|
+
"quote": "All employees must complete security awareness training annually.",
|
|
37
|
+
"claim": "Training is required every year",
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
print(cert.verdict) # "verified"
|
|
43
|
+
print(cert.confidence) # 0.92
|
|
44
|
+
print(cert.support.support_score) # 1.0
|
|
45
|
+
print(cert.contradictions) # []
|
|
46
|
+
|
|
47
|
+
# Output-only calls are accepted, but the SDK does not pretend certainty
|
|
48
|
+
# when no visible trace is supplied.
|
|
49
|
+
output_only = seal.verify(
|
|
50
|
+
output="Employees must complete security awareness training every year.",
|
|
51
|
+
task_type="policy",
|
|
52
|
+
)
|
|
53
|
+
print(output_only.verdict) # "insufficient_evidence"
|
|
54
|
+
print(output_only.insufficient_evidence_reasons) # ["missing_visible_support"]
|
|
55
|
+
|
|
56
|
+
# Optional: request the shadow extractor report for comparison/debugging
|
|
57
|
+
shadow_cert = seal.verify(
|
|
58
|
+
output="Employees must complete security awareness training every year.",
|
|
59
|
+
task_type="policy",
|
|
60
|
+
reasoning_steps=[
|
|
61
|
+
{
|
|
62
|
+
"role": "assistant",
|
|
63
|
+
"content": "Security policy requires annual training.",
|
|
64
|
+
"claims": ["Training is annual"],
|
|
65
|
+
"evidence": ["Policy 7.2"],
|
|
66
|
+
"confidence": 0.9,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
shadow_extraction=True,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
print(shadow_cert.shadow_extractor_status) # "success" | "skipped" | "error"
|
|
73
|
+
if shadow_cert.shadow_reasoning_integrity:
|
|
74
|
+
print(shadow_cert.shadow_reasoning_integrity.integrity_score)
|
|
75
|
+
if shadow_cert.shadow_extractor_error:
|
|
76
|
+
print(shadow_cert.shadow_extractor_error)
|
|
77
|
+
|
|
78
|
+
# Check usage
|
|
79
|
+
usage = seal.get_usage()
|
|
80
|
+
print(f"Today: {usage.today_count}/{usage.daily_limit}")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
API keys use the `rp_` family of prefixes. Self-serve trial keys use
|
|
84
|
+
`rp_free_`, paid pilot keys use `rp_live_`, and founder keys use
|
|
85
|
+
`rp_founder_`.
|
|
86
|
+
|
|
87
|
+
## Policy And Shadow Extraction
|
|
88
|
+
|
|
89
|
+
`reasoning_steps` is optional, but stronger verdicts require visible support.
|
|
90
|
+
If you only send the final output, Proof Seal will usually return
|
|
91
|
+
`insufficient_evidence` instead of a strong verification verdict.
|
|
92
|
+
|
|
93
|
+
For high-trust task types such as `policy`, `legal_internal`, and
|
|
94
|
+
`finance_ops`, `verified` is stricter than a generic confidence label. In
|
|
95
|
+
those workflows, Proof Seal will not return `verified` if unresolved
|
|
96
|
+
unsupported claims remain after visible-evidence reconciliation.
|
|
97
|
+
|
|
98
|
+
When a request resolves to `insufficient_evidence`, the certificate also
|
|
99
|
+
includes machine-readable `insufficient_evidence_reasons`. The SDK exports the
|
|
100
|
+
canonical taxonomy as `INSUFFICIENT_EVIDENCE_REASONS` plus
|
|
101
|
+
`is_insufficient_evidence_reason()` so callers can branch on stable reason IDs
|
|
102
|
+
instead of ad-hoc strings:
|
|
103
|
+
|
|
104
|
+
- `missing_visible_support`
|
|
105
|
+
- `weak_support_present`
|
|
106
|
+
- `unsupported_claims_present`
|
|
107
|
+
- `missing_grounded_citations`
|
|
108
|
+
- `missing_successful_tool_call`
|
|
109
|
+
|
|
110
|
+
When a request resolves to `policy_rejected`, the certificate also includes
|
|
111
|
+
machine-readable `policy_rejection_reasons`. The SDK exports the canonical
|
|
112
|
+
taxonomy as `POLICY_REJECTION_REASONS` plus `is_policy_rejection_reason()`:
|
|
113
|
+
|
|
114
|
+
- `integrity_below_minimum`
|
|
115
|
+
- `support_below_minimum`
|
|
116
|
+
- `contradictions_present`
|
|
117
|
+
- `unsupported_claims_present`
|
|
118
|
+
- `missing_required_grounded_citations`
|
|
119
|
+
- `missing_required_successful_tool_call`
|
|
120
|
+
- `unsafe_content_detected`
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from remembr_proof import (
|
|
124
|
+
INSUFFICIENT_EVIDENCE_REASONS,
|
|
125
|
+
POLICY_REJECTION_REASONS,
|
|
126
|
+
ProofSeal,
|
|
127
|
+
is_insufficient_evidence_reason,
|
|
128
|
+
is_policy_rejection_reason,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
cert = seal.verify(
|
|
132
|
+
output="Critical decision output.",
|
|
133
|
+
task_type="policy",
|
|
134
|
+
retrieved_context=[
|
|
135
|
+
{"id": "policy-7.2", "content": "All employees must complete security awareness training annually."},
|
|
136
|
+
],
|
|
137
|
+
citations=[
|
|
138
|
+
{"source_id": "policy-7.2", "quote": "All employees must complete security awareness training annually."},
|
|
139
|
+
],
|
|
140
|
+
policy={
|
|
141
|
+
"min_support_score": 0.75,
|
|
142
|
+
"require_grounded_citations": True,
|
|
143
|
+
},
|
|
144
|
+
shadow_extraction=True,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
print(cert.is_policy_rejected)
|
|
148
|
+
print(cert.policy_violations)
|
|
149
|
+
print(POLICY_REJECTION_REASONS)
|
|
150
|
+
print(cert.shadow_extractor_status)
|
|
151
|
+
print(INSUFFICIENT_EVIDENCE_REASONS)
|
|
152
|
+
|
|
153
|
+
for reason in cert.policy_rejection_reasons:
|
|
154
|
+
assert is_policy_rejection_reason(reason)
|
|
155
|
+
|
|
156
|
+
for reason in cert.insufficient_evidence_reasons:
|
|
157
|
+
assert is_insufficient_evidence_reason(reason)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Middleware (OpenAI / Anthropic)
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from openai import OpenAI
|
|
164
|
+
from remembr_proof import with_proof_seal
|
|
165
|
+
|
|
166
|
+
client = with_proof_seal(OpenAI(), api_key="rp_live_YOUR_KEY")
|
|
167
|
+
|
|
168
|
+
response = client.chat.completions.create(
|
|
169
|
+
model="gpt-5.5",
|
|
170
|
+
messages=[{"role": "user", "content": "Summarize the quarterly numbers."}],
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
print(response.proof_certificate.verdict)
|
|
174
|
+
print(response.proof_certificate.confidence)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## OpenAI Agents SDK
|
|
178
|
+
|
|
179
|
+
Install the optional agent dependency:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
pip install "remembr-proof[agents]"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Wrap an OpenAI Agents SDK agent to verify the final output and visible run trace before your application trusts the result:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from agents import Agent, function_tool
|
|
189
|
+
from remembr_proof import ProofSeal, VerifiedAgent
|
|
190
|
+
|
|
191
|
+
@function_tool
|
|
192
|
+
def lookup_policy(query: str) -> str:
|
|
193
|
+
return "Security awareness training is annual."
|
|
194
|
+
|
|
195
|
+
agent = Agent(name="Policy researcher", tools=[lookup_policy])
|
|
196
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
197
|
+
verified_agent = VerifiedAgent(
|
|
198
|
+
agent,
|
|
199
|
+
seal,
|
|
200
|
+
task_type="policy",
|
|
201
|
+
policy={"min_support_score": 0.75, "require_successful_tool_call": True},
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
result = verified_agent.run_sync("Can employees skip annual security training?")
|
|
205
|
+
|
|
206
|
+
print(result.final_output)
|
|
207
|
+
print(result.certificate.verdict)
|
|
208
|
+
print(result.is_verified)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`VerifiedAgent` keeps `openai-agents` as a soft dependency. Importing `remembr_proof` does not require it; the dependency is required only when `VerifiedAgent.run()` or `VerifiedAgent.run_sync()` is called.
|
|
212
|
+
|
|
213
|
+
## Perplexity Pro Search
|
|
214
|
+
|
|
215
|
+
Use `PerplexityClient` for Sonar API research and `VerifiedSearch` to verify the answer plus returned citations before trusting it:
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
from remembr_proof import PerplexityClient, ProofSeal, VerifiedSearch
|
|
219
|
+
|
|
220
|
+
search = VerifiedSearch(
|
|
221
|
+
PerplexityClient(api_key="pplx_YOUR_KEY"),
|
|
222
|
+
ProofSeal(api_key="rp_live_YOUR_KEY"),
|
|
223
|
+
task_type="research",
|
|
224
|
+
policy={"require_grounded_citations": True, "reject_on_contradictions": True},
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
result = search.query("What changed in the market this week?")
|
|
228
|
+
print(result.answer)
|
|
229
|
+
print(result.verdict)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Perplexity output is external research, not proof. Store the returned Proof Seal certificate id and review unresolved contradictions before acting on the answer.
|
|
233
|
+
|
|
234
|
+
## Own Special Ability: Adversarial Synthesis
|
|
235
|
+
|
|
236
|
+
Use `AdversarialSynthesis` when you want REMEMBR to verify both a claim and its strongest challenge before reporting what survived:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from remembr_proof import AdversarialSynthesis, ProofSeal
|
|
240
|
+
|
|
241
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
242
|
+
synthesis = AdversarialSynthesis(seal)
|
|
243
|
+
|
|
244
|
+
result = synthesis.run_sync(
|
|
245
|
+
claim="Enterprise AI spend will reach $297B by 2027.",
|
|
246
|
+
evidence=[{"id": "src-1", "content": "AI spending projected at $297B by 2027."}],
|
|
247
|
+
citations=[{"source_id": "src-1", "quote": "$297B by 2027", "claim": "$297B by 2027"}],
|
|
248
|
+
task_type="research",
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
print(result.synthesis_verdict)
|
|
252
|
+
print(result.refined_confidence)
|
|
253
|
+
print(result.crux)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The public Worker packet for this ability is `GET /api/own-special-ability`; the admin advisory packet is `GET /api/admin/synthesis`.
|
|
257
|
+
|
|
258
|
+
## Real Client Use Cases
|
|
259
|
+
|
|
260
|
+
The repo includes concrete client workflow packets:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
python examples/created-features/client-real-life-use-cases.py --dry-run
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The dry run does not call the API. It shows the payloads for support QA, legal notice-period review, finance invoice checks, compliance policy answers, market research packets, and release notes gated on tool output.
|
|
267
|
+
|
|
268
|
+
Run live only after setting credentials and a base URL:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
REMEMBR_PROOF_API_KEY=rp_live_YOUR_KEY \
|
|
272
|
+
REMEMBR_PROOF_BASE_URL=http://127.0.0.1:8787 \
|
|
273
|
+
python examples/created-features/client-real-life-use-cases.py --live
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Computer Code Runner
|
|
277
|
+
|
|
278
|
+
Use `CodeRunner` for local subprocess execution and `VerifiedCodeRunner` when you want Proof Seal to verify captured output as a tool result:
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from remembr_proof import CodeRunner, ProofSeal, VerifiedCodeRunner
|
|
282
|
+
|
|
283
|
+
runner = VerifiedCodeRunner(
|
|
284
|
+
CodeRunner(timeout=10),
|
|
285
|
+
ProofSeal(api_key="rp_live_YOUR_KEY"),
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
result = runner.run_python("print(2 + 2)")
|
|
289
|
+
print(result.stdout)
|
|
290
|
+
print(result.certificate.verdict if result.certificate else "unverified")
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
`CodeRunner` is not a sandbox. Run untrusted code in a container or VM and do not grant it access to secrets or private data.
|
|
294
|
+
|
|
295
|
+
## Pricing
|
|
296
|
+
|
|
297
|
+
| Tier | Base | Per Verification | Daily Limit | Monthly Limit | Rate Limit |
|
|
298
|
+
|------|------|-----------------|-------------|---------------|------------|
|
|
299
|
+
| Free | $0/mo | $0 | 100 | 2,000 | 10/min |
|
|
300
|
+
| Pro | $49/mo | $0.005 | 10,000 | 300,000 | 60/min |
|
|
301
|
+
| Scale | $299/mo | $0.003 | 100,000 | 3,000,000 | 300/min |
|
|
302
|
+
| Enterprise | Custom | $0.001 | 1,000,000 | 30,000,000 | 1,000/min |
|
|
303
|
+
|
|
304
|
+
## Error Handling
|
|
305
|
+
|
|
306
|
+
All API errors raise `VerificationError`. The `status_code` attribute holds the HTTP status:
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
from remembr_proof import ProofSeal, VerificationError
|
|
310
|
+
|
|
311
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY")
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
cert = seal.verify(output="...", task_type="policy")
|
|
315
|
+
except VerificationError as e:
|
|
316
|
+
if e.status_code == 401:
|
|
317
|
+
print("Invalid or revoked API key")
|
|
318
|
+
elif e.status_code == 429:
|
|
319
|
+
print("Rate limit or daily/monthly quota exceeded — back off and retry")
|
|
320
|
+
elif e.status_code == 400:
|
|
321
|
+
print(f"Bad request: {e}")
|
|
322
|
+
else:
|
|
323
|
+
print(f"API error {e.status_code}: {e}")
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Connection failures (DNS, timeout) also raise `VerificationError` with `status_code = 0`.
|
|
327
|
+
|
|
328
|
+
The SDK has no built-in retry logic. For production use, wrap calls with your own exponential backoff on `429` and `5xx` responses.
|
|
329
|
+
|
|
330
|
+
## Timeouts
|
|
331
|
+
|
|
332
|
+
The default request timeout is **30 seconds**. Override it at construction time:
|
|
333
|
+
|
|
334
|
+
```python
|
|
335
|
+
seal = ProofSeal(api_key="rp_live_YOUR_KEY", timeout=60)
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Dependencies
|
|
339
|
+
|
|
340
|
+
The SDK uses the Python standard library only (`urllib`, `dataclasses`, `json`). No third-party packages are required.
|