sovereign-fastapi 1.0.0__py3-none-any.whl
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.
- sovereign_fastapi/__init__.py +3 -0
- sovereign_fastapi/middleware.py +158 -0
- sovereign_fastapi/py.typed +0 -0
- sovereign_fastapi-1.0.0.dist-info/METADATA +406 -0
- sovereign_fastapi-1.0.0.dist-info/RECORD +7 -0
- sovereign_fastapi-1.0.0.dist-info/WHEEL +5 -0
- sovereign_fastapi-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
# stdlib
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Any, Callable, Awaitable, Optional
|
|
7
|
+
|
|
8
|
+
# framework
|
|
9
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
10
|
+
from starlette.requests import Request
|
|
11
|
+
from starlette.responses import JSONResponse, Response
|
|
12
|
+
from starlette.types import ASGIApp
|
|
13
|
+
|
|
14
|
+
# local
|
|
15
|
+
from sovereign_core.gateway import SovereignGateway
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger("sovereign_fastapi")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SovereignMiddleware(BaseHTTPMiddleware):
|
|
21
|
+
"""Drop-in Starlette/FastAPI ASGI middleware that wraps the Sovereign sieve-and-sign
|
|
22
|
+
pipeline around every inbound JSON request.
|
|
23
|
+
|
|
24
|
+
On each request that carries a JSON body the middleware:
|
|
25
|
+
|
|
26
|
+
1. Extracts the target text (either the value of ``payload_field`` or the
|
|
27
|
+
entire serialised body when no field is specified).
|
|
28
|
+
2. Calls :meth:`~sovereign_core.gateway.SovereignGateway.sieve_and_sign`
|
|
29
|
+
to strip Prose Tax filler, normalise whitespace, and produce a signed
|
|
30
|
+
:class:`~sovereign_core.crypto.ForensicReceipt`.
|
|
31
|
+
3. Overwrites ``request._body`` with the optimised payload so that every
|
|
32
|
+
downstream route handler transparently receives the cleaned text without
|
|
33
|
+
any code changes on its side.
|
|
34
|
+
4. Stores the sealed receipt at ``request.state.sovereign_receipt`` for
|
|
35
|
+
in-route auditability.
|
|
36
|
+
5. Injects two headers into the outbound response:
|
|
37
|
+
- ``X-Sovereign-Receipt-Signature`` — the base64-encoded Ed25519 signature.
|
|
38
|
+
- ``X-Sovereign-Tokens-Saved`` — the cumulative FinOps savings counter.
|
|
39
|
+
|
|
40
|
+
The underlying :meth:`sieve_and_sign` macro captures its
|
|
41
|
+
:class:`~sovereign_core.gateway.OptimizationReceipt` in coroutine-local
|
|
42
|
+
scope, so concurrent requests sharing the same middleware instance never
|
|
43
|
+
bleed per-request metrics into each other's receipts.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
app: The downstream ASGI application to wrap.
|
|
47
|
+
signing_key: Path to the Ed25519 private key PEM file. Forwarded
|
|
48
|
+
directly to :class:`~sovereign_core.gateway.SovereignGateway`.
|
|
49
|
+
Defaults to ``.keys/sovereign_identity.pem``.
|
|
50
|
+
strict_mode: When ``True``, any exception raised during body
|
|
51
|
+
interception (JSON decode error, missing field, key
|
|
52
|
+
initialisation failure) causes the middleware to abort and
|
|
53
|
+
return an HTTP 422 Unprocessable Entity response instead of
|
|
54
|
+
falling through to the downstream handler. Defaults to
|
|
55
|
+
``False``.
|
|
56
|
+
payload_field: Optional key name to extract from the JSON body as
|
|
57
|
+
the text to sieve. When ``None``, the entire body is
|
|
58
|
+
serialised with :func:`json.dumps` and treated as the input
|
|
59
|
+
string. Defaults to ``None``.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
app: ASGIApp,
|
|
65
|
+
*,
|
|
66
|
+
signing_key: str = ".keys/sovereign_identity.pem",
|
|
67
|
+
strict_mode: bool = False,
|
|
68
|
+
payload_field: Optional[str] = None,
|
|
69
|
+
) -> None:
|
|
70
|
+
super().__init__(app)
|
|
71
|
+
self.gateway = SovereignGateway(signing_key=signing_key)
|
|
72
|
+
self.strict_mode = strict_mode
|
|
73
|
+
self.payload_field = payload_field
|
|
74
|
+
|
|
75
|
+
async def dispatch(
|
|
76
|
+
self,
|
|
77
|
+
request: Request,
|
|
78
|
+
call_next: Callable[[Request], Awaitable[Response]],
|
|
79
|
+
) -> Response:
|
|
80
|
+
content_type = request.headers.get("content-type", "")
|
|
81
|
+
receipt: Any = None
|
|
82
|
+
|
|
83
|
+
if "application/json" in content_type:
|
|
84
|
+
# Buffer the body. _CachedRequest.wrapped_receive (Starlette's
|
|
85
|
+
# internal mechanism for replaying the body to downstream handlers)
|
|
86
|
+
# returns self._body verbatim when it is set. Overwriting _body
|
|
87
|
+
# after this call is therefore the correct way to transparently
|
|
88
|
+
# inject a modified payload for every consumer downstream.
|
|
89
|
+
body_bytes = await request.body()
|
|
90
|
+
new_body = body_bytes # default: pass through unchanged on error
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
body_json = json.loads(body_bytes)
|
|
94
|
+
|
|
95
|
+
if self.payload_field is not None:
|
|
96
|
+
target_text = str(body_json[self.payload_field])
|
|
97
|
+
else:
|
|
98
|
+
target_text = json.dumps(body_json, ensure_ascii=False)
|
|
99
|
+
|
|
100
|
+
result = await self.gateway.sieve_and_sign(target_text)
|
|
101
|
+
receipt = result.receipt
|
|
102
|
+
request.state.sovereign_receipt = receipt
|
|
103
|
+
|
|
104
|
+
if self.payload_field is not None:
|
|
105
|
+
body_json[self.payload_field] = result.content
|
|
106
|
+
new_body = json.dumps(body_json, ensure_ascii=False).encode("utf-8")
|
|
107
|
+
else:
|
|
108
|
+
new_body = result.content.encode("utf-8")
|
|
109
|
+
|
|
110
|
+
except Exception as exc:
|
|
111
|
+
if self.strict_mode:
|
|
112
|
+
logger.critical(
|
|
113
|
+
"Sovereign boundary processing failed under strict enforcement. "
|
|
114
|
+
"Aborting request.",
|
|
115
|
+
exc_info=True,
|
|
116
|
+
)
|
|
117
|
+
return JSONResponse(
|
|
118
|
+
{"detail": f"Sovereign middleware validation error: {exc}"},
|
|
119
|
+
status_code=422,
|
|
120
|
+
)
|
|
121
|
+
logger.error(
|
|
122
|
+
"Sovereign boundary processing failed. "
|
|
123
|
+
"Bypassing defensively to ensure system availability.",
|
|
124
|
+
exc_info=True,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Overwrite the _CachedRequest body cache. Every downstream
|
|
128
|
+
# receive() call issued by Starlette's routing layer will replay
|
|
129
|
+
# this value instead of the original stream.
|
|
130
|
+
request._body = new_body # type: ignore[attr-defined]
|
|
131
|
+
|
|
132
|
+
# Realign Content-Length with the (possibly sieved) body so that
|
|
133
|
+
# downstream ASGI handlers, routers, and reverse proxies never
|
|
134
|
+
# encounter a stale-length mismatch against the overwritten body
|
|
135
|
+
# bytes or a hanging read timeout waiting for bytes that no longer
|
|
136
|
+
# exist.
|
|
137
|
+
new_content_length = str(len(new_body)).encode("utf-8")
|
|
138
|
+
scope_headers = request.scope["headers"]
|
|
139
|
+
patched = [
|
|
140
|
+
(n, new_content_length if n == b"content-length" else v)
|
|
141
|
+
for n, v in scope_headers
|
|
142
|
+
]
|
|
143
|
+
if not any(n == b"content-length" for n, _ in scope_headers):
|
|
144
|
+
patched.append((b"content-length", new_content_length))
|
|
145
|
+
request.scope["headers"] = patched
|
|
146
|
+
|
|
147
|
+
response = await call_next(request)
|
|
148
|
+
|
|
149
|
+
if receipt is not None:
|
|
150
|
+
response.headers["X-Sovereign-Receipt-Signature"] = receipt["signature"]
|
|
151
|
+
tokens_saved = (
|
|
152
|
+
receipt["metadata"]
|
|
153
|
+
.get("prose_tax_summary", {})
|
|
154
|
+
.get("total_tokens_saved", 0)
|
|
155
|
+
)
|
|
156
|
+
response.headers["X-Sovereign-Tokens-Saved"] = str(tokens_saved)
|
|
157
|
+
|
|
158
|
+
return response
|
|
File without changes
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sovereign-fastapi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: FastAPI/Starlette ASGI middleware for the Sovereign Systems SDK
|
|
5
|
+
Author-email: kenwalger <kenalger@comcast.net>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/kenwalger/sovereign-sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/kenwalger/sovereign-sdk
|
|
9
|
+
Project-URL: Changelog, https://github.com/kenwalger/sovereign-sdk/blob/main/CHANGELOG.md
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Security
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: sovereign-core<2.0.0,>=1.0.0
|
|
18
|
+
Requires-Dist: starlette<1.0.0,>=0.35.0
|
|
19
|
+
|
|
20
|
+
# Sovereign Systems SDK
|
|
21
|
+
|
|
22
|
+
**High-Integrity Cryptographic Provenance and Inbound Protection Boundaries for Agentic Workflows.**
|
|
23
|
+
|
|
24
|
+
Sovereign Systems is a local-first AI WAF and compliance gate. It intercepts every inbound payload before it reaches a model or agentic loop, strips high-entropy boilerplate, and seals the result with an Ed25519-signed `ForensicReceipt` that gives enterprise auditors mathematical proof of un-tampered boundary transformation — all running on local silicon with no external service dependency.
|
|
25
|
+
|
|
26
|
+
Every boundary crossing produces a non-repudiable chain of custody: the receipt binds the sieved payload hash and the full transformation accounting inside a single cryptographic envelope. No post-hoc mutation of the output or its metrics can go undetected.
|
|
27
|
+
|
|
28
|
+
To learn more about the philosophy and reasoning behind this project, see [PHILOSOPHY.md](PHILOSOPHY.md).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Why an AI WAF?
|
|
33
|
+
|
|
34
|
+
Modern agentic pipelines ingest user intent through prompt text. That text is routinely bloated with conversational filler — greetings, hedging adverbs, redundant preambles — that inflates token budgets and introduces non-deterministic reasoning noise without contributing semantic content. At the same time, enterprises operating LLM workloads need the same compliance guarantees they expect from a network WAF: proof that payloads were inspected, proof that the inspection was faithful, and an append-only audit log that is tamper-evident after the fact.
|
|
35
|
+
|
|
36
|
+
Sovereign Systems provides both:
|
|
37
|
+
|
|
38
|
+
- **Inbound boundary enforcement** — every payload is sieved before a model or tool sees it.
|
|
39
|
+
- **Cryptographic chain of custody** — every sieved payload is sealed with a node-local Ed25519 private key into a `ForensicReceipt` that persists forever.
|
|
40
|
+
- **Non-repudiation** — the receipt covers the output hash and the transformation accounting under the same signature, so neither the result nor the metrics can be altered without breaking verification.
|
|
41
|
+
- **Local-only execution** — no telemetry leaves the host; key material never leaves the node.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Workspace Topography
|
|
46
|
+
|
|
47
|
+
This repository is managed as an integrated `uv` workspace separating the cryptographic data tier from the execution runtime:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
.
|
|
51
|
+
├── packages/
|
|
52
|
+
│ ├── sovereign-core/ # Pure data tier (zero high-compute dependencies)
|
|
53
|
+
│ │ └── src/sovereign_core/
|
|
54
|
+
│ │ ├── crypto.py # Ed25519 key management & ForensicReceipt minting
|
|
55
|
+
│ │ └── gateway.py # Prose Tax sieve & SovereignGateway high-level API
|
|
56
|
+
│ │
|
|
57
|
+
│ ├── sovereign-runtime/ # Compute/Execution tier (tool & model isolation)
|
|
58
|
+
│ │ └── src/sovereign_runtime/
|
|
59
|
+
│ │ ├── router.py # Intent-based pre-flight namespace exposure
|
|
60
|
+
│ │ └── __main__.py # Execution runtime entry point
|
|
61
|
+
│ │
|
|
62
|
+
│ └── sovereign-fastapi/ # FastAPI/Starlette ASGI middleware adapter
|
|
63
|
+
│ └── src/sovereign_fastapi/
|
|
64
|
+
│ └── middleware.py # SovereignMiddleware — sieve-and-sign request interceptor
|
|
65
|
+
│
|
|
66
|
+
├── pyproject.toml # Monorepo configuration & workspace links
|
|
67
|
+
└── uv.lock # Deterministic dependency lockfile
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## The ForensicReceipt: Sealed Transformation Accounting
|
|
73
|
+
|
|
74
|
+
Every boundary crossing produces a `ForensicReceipt`. Understanding its structure explains exactly what an enterprise auditor can prove from the output alone.
|
|
75
|
+
|
|
76
|
+
### What is sealed
|
|
77
|
+
|
|
78
|
+
The Ed25519 signature inside every receipt covers a single canonical manifest:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"metadata": { ... },
|
|
83
|
+
"payload_hash": "<sha256-of-sieved-content>",
|
|
84
|
+
"timestamp": "<utc-iso8601>"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`payload_hash` is the SHA-256 digest of the exact sieved string delivered to the model or tool. When the Prose Tax sieve is active, `metadata` always contains a `prose_tax_summary` sub-object:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
"prose_tax_summary": {
|
|
92
|
+
"raw_token_count": 12,
|
|
93
|
+
"optimized_token_count": 4,
|
|
94
|
+
"tokens_eliminated": 8,
|
|
95
|
+
"tax_savings_percentage": 66.6667,
|
|
96
|
+
"total_tokens_saved": 8
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Because `metadata` is bound inside the signed manifest, these token counts are just as tamper-evident as `payload_hash` itself. An auditor who holds only the node's public key can independently verify:
|
|
101
|
+
|
|
102
|
+
1. **Output integrity** — the sieved content hasn't been altered after signing (`payload_hash`).
|
|
103
|
+
2. **Transformation accounting** — the before/after token delta recorded at signing time hasn't been fabricated (`prose_tax_summary` is sealed under the same signature).
|
|
104
|
+
3. **Identity provenance** — the receipt was minted by the expected node, not a rogue keypair (`public_key` key-pin assertion).
|
|
105
|
+
|
|
106
|
+
Together these three checks give mathematical proof that the boundary transformation was faithful and un-tampered — equivalent to a signed audit log with built-in integrity verification.
|
|
107
|
+
|
|
108
|
+
### Verification workflow
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
import asyncio
|
|
112
|
+
import json
|
|
113
|
+
from sovereign_core.gateway import SovereignGateway
|
|
114
|
+
from sovereign_core.crypto import SovereignKeyManager
|
|
115
|
+
|
|
116
|
+
async def main():
|
|
117
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
118
|
+
result = await gateway.sieve_and_sign("Hi! Please just help me now.")
|
|
119
|
+
|
|
120
|
+
# result.content == "help me now"
|
|
121
|
+
# result.receipt["metadata"]["prose_tax_summary"]["tokens_eliminated"] == 4
|
|
122
|
+
|
|
123
|
+
# Verify later — requires only the public key and the original sieved payload
|
|
124
|
+
is_valid = SovereignKeyManager.verify_receipt(
|
|
125
|
+
result.receipt,
|
|
126
|
+
{"content": result.content},
|
|
127
|
+
expected_public_key=gateway.export_public_key(),
|
|
128
|
+
)
|
|
129
|
+
assert is_valid # fails if any field was mutated after signing
|
|
130
|
+
|
|
131
|
+
asyncio.run(main())
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Primary Developer Interface: `SovereignGateway`
|
|
137
|
+
|
|
138
|
+
`SovereignGateway` is the single entry point for application code. It wraps the full sieve-and-sign pipeline behind a clean four-method API.
|
|
139
|
+
|
|
140
|
+
### One-shot macro (recommended)
|
|
141
|
+
|
|
142
|
+
`sieve_and_sign()` strips Prose Tax boilerplate, fuses the transformation telemetry into the receipt metadata, and seals everything in a single awaitable call:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
import asyncio
|
|
146
|
+
from sovereign_core.gateway import SovereignGateway
|
|
147
|
+
|
|
148
|
+
async def main():
|
|
149
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
150
|
+
result = await gateway.sieve_and_sign("Hi! Please just help me now.")
|
|
151
|
+
|
|
152
|
+
# result — SovereignBoundaryResponse (Pydantic model, fully typed)
|
|
153
|
+
# result.content — purified string, Prose Tax stripped ("help me now")
|
|
154
|
+
# result.receipt — ForensicReceipt with prose_tax_summary sealed inside
|
|
155
|
+
|
|
156
|
+
print(result.content)
|
|
157
|
+
print(result.receipt["payload_hash"])
|
|
158
|
+
|
|
159
|
+
asyncio.run(main())
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Inside a FastAPI route the gateway instance lives on the application object; the route itself is already async:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from sovereign_core.gateway import SovereignGateway
|
|
166
|
+
|
|
167
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
168
|
+
|
|
169
|
+
@app.post("/api/v1/ingest")
|
|
170
|
+
async def handle_agent_input(raw_payload: dict):
|
|
171
|
+
result = await gateway.sieve_and_sign(raw_payload["text"])
|
|
172
|
+
|
|
173
|
+
await reasoning_ledger.append(
|
|
174
|
+
payload=result.content,
|
|
175
|
+
receipt=result.receipt,
|
|
176
|
+
)
|
|
177
|
+
return {
|
|
178
|
+
"status": "sovereign_verified",
|
|
179
|
+
"receipt_id": result.receipt["payload_hash"],
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Granular two-step workflow
|
|
184
|
+
|
|
185
|
+
When the clean context is needed before signing (e.g. for intermediate validation or logging):
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
import asyncio
|
|
189
|
+
from sovereign_core.gateway import SovereignGateway
|
|
190
|
+
|
|
191
|
+
async def main():
|
|
192
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
193
|
+
|
|
194
|
+
# 1. Strip Prose Tax — remove boilerplate, normalize whitespace
|
|
195
|
+
clean_context = await gateway.sieve("Hi! Please just help me now.")
|
|
196
|
+
|
|
197
|
+
# 2. Cryptographically seal — transformation telemetry fused into metadata
|
|
198
|
+
receipt = gateway.sign(clean_context)
|
|
199
|
+
|
|
200
|
+
print(clean_context) # "help me now"
|
|
201
|
+
print(receipt["payload_hash"]) # SHA-256 of {"content": "help me now"}
|
|
202
|
+
|
|
203
|
+
asyncio.run(main())
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Independent receipt verification
|
|
207
|
+
|
|
208
|
+
Receipts produced by either workflow can be verified at any time using only the public key:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from sovereign_core.crypto import SovereignKeyManager
|
|
212
|
+
|
|
213
|
+
is_valid = SovereignKeyManager.verify_receipt(
|
|
214
|
+
receipt,
|
|
215
|
+
{"content": clean_context},
|
|
216
|
+
expected_public_key=gateway.export_public_key(),
|
|
217
|
+
)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## ASGI Middleware for FastAPI / Starlette
|
|
223
|
+
|
|
224
|
+
`SovereignMiddleware` applies the sieve-and-sign boundary to every inbound JSON request transparently, without changes to route handlers:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from fastapi import FastAPI
|
|
228
|
+
from sovereign_fastapi.middleware import SovereignMiddleware
|
|
229
|
+
|
|
230
|
+
app = FastAPI()
|
|
231
|
+
app.add_middleware(
|
|
232
|
+
SovereignMiddleware,
|
|
233
|
+
signing_key=".keys/sovereign_identity.pem",
|
|
234
|
+
payload_field="text", # JSON key to sieve; omit to sieve the whole body
|
|
235
|
+
strict_mode=False, # True → return HTTP 422 on any interception error
|
|
236
|
+
)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The middleware:
|
|
240
|
+
1. Extracts the target field from the JSON body.
|
|
241
|
+
2. Calls `sieve_and_sign()` on the gateway.
|
|
242
|
+
3. Overwrites `request._body` so every downstream route handler sees the sieved payload.
|
|
243
|
+
4. Caches the sealed receipt at `request.state.sovereign_receipt`.
|
|
244
|
+
5. Injects `X-Sovereign-Receipt-Signature` and `X-Sovereign-Tokens-Saved` on the outbound response.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Prose Tax Optimization
|
|
249
|
+
|
|
250
|
+
> **This feature is optional.** The cryptographic boundary and ForensicReceipt are produced whether or not any text is eliminated. Prose Tax optimization runs inside the audit envelope — every token count and savings metric is sealed alongside the output hash.
|
|
251
|
+
|
|
252
|
+
The sieve removes conversational boilerplate that inflates token budgets without contributing semantic content:
|
|
253
|
+
|
|
254
|
+
| Category | Examples stripped |
|
|
255
|
+
|---|---|
|
|
256
|
+
| Greeting tokens | `hi`, `hello`, `hey`, `greetings` |
|
|
257
|
+
| Hedging adverbs | `just`, `simply`, `actually`, `basically`, `probably` |
|
|
258
|
+
| Affirmation filler | `of course`, `certainly`, `absolutely`, `sure` |
|
|
259
|
+
| Preamble phrases | `I hope this`, `I hope that`, `I hope you` |
|
|
260
|
+
| Politeness tokens | `please`, `kindly` |
|
|
261
|
+
|
|
262
|
+
All patterns carry negative lookahead guards (e.g. `(?![-\w])`) so technical compound words (`hi-fi`, `just-in-time`, `certainly-not`) pass through unmarred.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Local Development
|
|
267
|
+
|
|
268
|
+
### Bootstrap
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
uv sync
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Run tests
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
uv run pytest
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Run the sovereign-node runtime
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
uv run sovereign-node
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Running the Workspace Examples
|
|
289
|
+
|
|
290
|
+
### FastAPI Gateway Example
|
|
291
|
+
|
|
292
|
+
**1. Set your node secret** (required for Ed25519 key generation):
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
export SOVEREIGN_NODE_SECRET=your-local-secret # Linux / macOS
|
|
296
|
+
$env:SOVEREIGN_NODE_SECRET = "your-local-secret" # Windows PowerShell
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**2. Start the example server:**
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
uv run uvicorn examples.fastapi_gateway.app:app --reload
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The server starts on `http://127.0.0.1:8000`. On first boot it generates an Ed25519 keypair at `.keys/example_identity.pem`.
|
|
306
|
+
|
|
307
|
+
**3. In a second terminal, run the example client:**
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
uv run python examples/fastapi_gateway/client.py
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Verifying a ForensicReceipt (CLI)
|
|
314
|
+
|
|
315
|
+
Export a receipt and the gateway's public key:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
import asyncio
|
|
319
|
+
import json
|
|
320
|
+
from sovereign_core.gateway import SovereignGateway
|
|
321
|
+
|
|
322
|
+
async def main():
|
|
323
|
+
gateway = SovereignGateway()
|
|
324
|
+
result = await gateway.sieve_and_sign("example payload")
|
|
325
|
+
|
|
326
|
+
with open("receipt.json", "w") as f:
|
|
327
|
+
json.dump(result.receipt, f, indent=2)
|
|
328
|
+
|
|
329
|
+
print(gateway.export_public_key())
|
|
330
|
+
|
|
331
|
+
asyncio.run(main())
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Verify the receipt:
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
uv run sovereign-verify \
|
|
338
|
+
--receipt receipt.json \
|
|
339
|
+
--public-key <base64-encoded-public-key>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
On success:
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
Verified ✓ payload_hash: 4fec03e7...
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
On tampered receipt:
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
Tampered ✗ Receipt failed cryptographic verification.
|
|
352
|
+
payload_hash : 4fec03e7...
|
|
353
|
+
timestamp : 2026-05-22T...
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Verification & Deep-Dive Diagnostics
|
|
359
|
+
|
|
360
|
+
### Local Environment Configuration
|
|
361
|
+
|
|
362
|
+
`SOVEREIGN_NODE_SECRET` can be specified in a `.env` file at the repository root. The node entrypoint loads it automatically via `python-dotenv`:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
echo 'SOVEREIGN_NODE_SECRET=your-local-secret' > .env
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Standalone Tool Analysis Mode
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
uv run sovereign-node --tool analyze
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Expected Console Output
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
====================================================
|
|
378
|
+
🟢 Sovereign Node initialization sequence successful.
|
|
379
|
+
====================================================
|
|
380
|
+
🔄 Dispatching single tool execution: 'analyze'...
|
|
381
|
+
⚠️ Standalone mode detected: Context empty. Hydrating baseline diagnostic state...
|
|
382
|
+
|
|
383
|
+
🔒 Authenticated Forensic Receipt Proof:
|
|
384
|
+
{
|
|
385
|
+
"timestamp": "2026-05-22T15:00:00.000000+00:00",
|
|
386
|
+
"payload_hash": "4fec03e7083cca73cfb1152ae1d941b5a5a581fc725a43b3ee7df1d9ce697954",
|
|
387
|
+
"public_key": "<base64-encoded Ed25519 public key>",
|
|
388
|
+
"signature": "<base64-encoded Ed25519 signature>",
|
|
389
|
+
"metadata": {
|
|
390
|
+
"runtime": "async-sovereign-node",
|
|
391
|
+
"py_ver": "3.12.x",
|
|
392
|
+
"execution_success": true
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Line-by-line interpretation:**
|
|
398
|
+
|
|
399
|
+
| Output line | What it proves |
|
|
400
|
+
|---|---|
|
|
401
|
+
| `🟢 Sovereign Node initialization sequence successful.` | Ed25519 keypair loaded or generated; `SOVEREIGN_NODE_SECRET` resolved; router and session context initialised. |
|
|
402
|
+
| `⚠️ Standalone mode detected …` | The `analyze` tool detected no upstream context and self-hydrated a baseline telemetry stream — expected behaviour in single-tool invocations. |
|
|
403
|
+
| `"payload_hash": "4fec03e7…"` | SHA-256 digest of the deterministically serialised execution payload. |
|
|
404
|
+
| `"public_key": "<base64>"` | Base64-encoded raw Ed25519 public key; verified by `_audit_receipt` before process exit. |
|
|
405
|
+
| `"signature": "<base64>"` | Ed25519 signature over `{"metadata": …, "payload_hash": …, "timestamp": …}`. Any mutation of these fields after issuance causes `verify_receipt` to return `False`. |
|
|
406
|
+
| `"execution_success": true` | The tool completed without raising an exception; the receipt is audit-clean. |
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
sovereign_fastapi/__init__.py,sha256=I7y7C9IQsUMRAV5HxEqdKTaXoyFBOVQIcKr0YqBjcIk,79
|
|
2
|
+
sovereign_fastapi/middleware.py,sha256=sXaYnMFFqO9tpLmR_okj7zYvnZyC0md3NZ-F0iXMI3E,6890
|
|
3
|
+
sovereign_fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
sovereign_fastapi-1.0.0.dist-info/METADATA,sha256=vPpm9Y5MOzWCiLeLMa8WFb74z_nr8tPvdi-YPwmYje4,14702
|
|
5
|
+
sovereign_fastapi-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
6
|
+
sovereign_fastapi-1.0.0.dist-info/top_level.txt,sha256=8vPSE0N4U5jzc0YTepL1lDJgABbLePpqImOQyDvRg2c,18
|
|
7
|
+
sovereign_fastapi-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sovereign_fastapi
|