sovereignty-protocol 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.
- sovereignty_protocol-0.1.0/LICENSE +55 -0
- sovereignty_protocol-0.1.0/PKG-INFO +203 -0
- sovereignty_protocol-0.1.0/README.md +175 -0
- sovereignty_protocol-0.1.0/pyproject.toml +45 -0
- sovereignty_protocol-0.1.0/setup.cfg +4 -0
- sovereignty_protocol-0.1.0/src/sovereignty/__init__.py +43 -0
- sovereignty_protocol-0.1.0/src/sovereignty/__main__.py +52 -0
- sovereignty_protocol-0.1.0/src/sovereignty/exposure.py +27 -0
- sovereignty_protocol-0.1.0/src/sovereignty/exposure_budget.py +136 -0
- sovereignty_protocol-0.1.0/src/sovereignty/guardrails.py +94 -0
- sovereignty_protocol-0.1.0/src/sovereignty/lane_health.py +80 -0
- sovereignty_protocol-0.1.0/src/sovereignty/measured_exposure.py +173 -0
- sovereignty_protocol-0.1.0/src/sovereignty/packet.py +99 -0
- sovereignty_protocol-0.1.0/src/sovereignty/policy.py +163 -0
- sovereignty_protocol-0.1.0/src/sovereignty/py.typed +0 -0
- sovereignty_protocol-0.1.0/src/sovereignty/redaction.py +53 -0
- sovereignty_protocol-0.1.0/src/sovereignty/side_effect_review.py +148 -0
- sovereignty_protocol-0.1.0/src/sovereignty/side_effects.py +128 -0
- sovereignty_protocol-0.1.0/src/sovereignty/telemetry.py +245 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/PKG-INFO +203 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/SOURCES.txt +45 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/dependency_links.txt +1 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/entry_points.txt +2 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/requires.txt +6 -0
- sovereignty_protocol-0.1.0/src/sovereignty_protocol.egg-info/top_level.txt +1 -0
- sovereignty_protocol-0.1.0/tests/test_attestation_docs.py +26 -0
- sovereignty_protocol-0.1.0/tests/test_cli.py +85 -0
- sovereignty_protocol-0.1.0/tests/test_current_router_compatibility.py +123 -0
- sovereignty_protocol-0.1.0/tests/test_exposure.py +27 -0
- sovereignty_protocol-0.1.0/tests/test_exposure_budget.py +178 -0
- sovereignty_protocol-0.1.0/tests/test_guardrail_events.py +66 -0
- sovereignty_protocol-0.1.0/tests/test_hermes_local_router_example.py +137 -0
- sovereignty_protocol-0.1.0/tests/test_json_schemas.py +218 -0
- sovereignty_protocol-0.1.0/tests/test_lane_health.py +65 -0
- sovereignty_protocol-0.1.0/tests/test_measured_exposure.py +73 -0
- sovereignty_protocol-0.1.0/tests/test_packaging_release.py +86 -0
- sovereignty_protocol-0.1.0/tests/test_packet_serialization.py +72 -0
- sovereignty_protocol-0.1.0/tests/test_packet_telemetry.py +144 -0
- sovereignty_protocol-0.1.0/tests/test_policy_validation.py +171 -0
- sovereignty_protocol-0.1.0/tests/test_protocol_not_gateway_docs.py +63 -0
- sovereignty_protocol-0.1.0/tests/test_public_private_boundary_docs.py +54 -0
- sovereignty_protocol-0.1.0/tests/test_recording_boundary.py +77 -0
- sovereignty_protocol-0.1.0/tests/test_redaction.py +36 -0
- sovereignty_protocol-0.1.0/tests/test_review_packet.py +41 -0
- sovereignty_protocol-0.1.0/tests/test_shadow_lane_docs.py +22 -0
- sovereignty_protocol-0.1.0/tests/test_side_effect_review.py +106 -0
- sovereignty_protocol-0.1.0/tests/test_side_effects.py +99 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
|
10
|
+
|
|
11
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
|
12
|
+
|
|
13
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
|
14
|
+
|
|
15
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
|
16
|
+
|
|
17
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
|
18
|
+
|
|
19
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
|
20
|
+
|
|
21
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work.
|
|
22
|
+
|
|
23
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on or derived from the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link or bind by name to the interfaces of, the Work and Derivative Works thereof.
|
|
24
|
+
|
|
25
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
|
26
|
+
|
|
27
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
|
28
|
+
|
|
29
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
30
|
+
|
|
31
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work.
|
|
32
|
+
|
|
33
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, provided that You meet the following conditions:
|
|
34
|
+
|
|
35
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
|
36
|
+
|
|
37
|
+
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
|
38
|
+
|
|
39
|
+
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
|
40
|
+
|
|
41
|
+
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file.
|
|
42
|
+
|
|
43
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions.
|
|
44
|
+
|
|
45
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
|
46
|
+
|
|
47
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
48
|
+
|
|
49
|
+
8. Limitation of Liability. In no event and under no legal theory shall any Contributor be liable to You for damages arising in any way out of the use of or inability to use the Work.
|
|
50
|
+
|
|
51
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer support, warranty, indemnity, or other liability obligations and/or rights consistent with this License.
|
|
52
|
+
|
|
53
|
+
END OF TERMS AND CONDITIONS
|
|
54
|
+
|
|
55
|
+
Copyright 2026 Sovereignty contributors
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sovereignty-protocol
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local-first agent delegation protocol and reference implementation
|
|
5
|
+
Author: Sovereignty contributors
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/m0ntydad0n/sovereignty
|
|
8
|
+
Project-URL: Repository, https://github.com/m0ntydad0n/sovereignty
|
|
9
|
+
Project-URL: Issues, https://github.com/m0ntydad0n/sovereignty/issues
|
|
10
|
+
Keywords: agents,local-first,llm,privacy,protocol,router
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Topic :: Security
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
24
|
+
Requires-Dist: jsonschema>=4.0; extra == "dev"
|
|
25
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# Sovereignty
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
.-.
|
|
33
|
+
/___\
|
|
34
|
+
(|o o|)
|
|
35
|
+
.--.\_-_/ .--.
|
|
36
|
+
/ _ '-' _ \
|
|
37
|
+
/__/ | | \__\
|
|
38
|
+
| | | | | |
|
|
39
|
+
|__| |_____| |__|
|
|
40
|
+
/ | \
|
|
41
|
+
/___|___\
|
|
42
|
+
|
|
43
|
+
______ _ __
|
|
44
|
+
/ ___/ /___ _ _____ ________ (_)___ _____ / /___ __
|
|
45
|
+
\__ \/ __ \ | / / _ \/ ___/ _ \/ / __ `/ __ \/ __/ / / /
|
|
46
|
+
___/ / /_/ / |/ / __/ / / __/ / /_/ / / / / /_/ /_/ /
|
|
47
|
+
/____/\____/|___/\___/_/ \___/_/\__, /_/ /_/\__/\__, /
|
|
48
|
+
/____/ /____/
|
|
49
|
+
|
|
50
|
+
local models do the prep. your agent keeps authority.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Sovereignty is an open-source protocol and reference implementation for local-first agent delegation. It defines how local model lanes can perform private prep work — classification, extraction, drafting, code triage, and sensitivity checks — while a main agent retains authority over final answers and side effects.
|
|
54
|
+
|
|
55
|
+
Sovereignty is not an LLM gateway. It is a contract for local-prep / cloud-authority workflows; see `docs/protocol-not-gateway.md` for the design note on why this is a protocol, not a gateway:
|
|
56
|
+
|
|
57
|
+
- local lanes produce structured review packets;
|
|
58
|
+
- local lanes do not invoke side-effecting tools;
|
|
59
|
+
- model and lane metadata is redacted before it leaves the local boundary;
|
|
60
|
+
- cloud exposure claims are explicit about their trust model;
|
|
61
|
+
- measured exposure reports can attach evidence without leaking raw prompts or endpoints;
|
|
62
|
+
- proposed side effects use a strict review-only schema before any authority-bearing tool acts;
|
|
63
|
+
- callers can validate packets and policies before a main agent acts.
|
|
64
|
+
|
|
65
|
+
## Status
|
|
66
|
+
|
|
67
|
+
v0.1.0 protocol release. The public surface is intentionally small and falsifiable: schema contracts, policy checks, metadata redaction, measured exposure reporting, side-effect review boundaries, a sober threat model, and Hermes adapter examples.
|
|
68
|
+
|
|
69
|
+
Sovereignty is still not a router or gateway. The private router implementation can evolve independently; this repository publishes the boundary contract local-prep systems must satisfy before an authority-bearing agent acts.
|
|
70
|
+
|
|
71
|
+
## Repository layout
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
sovereignty/
|
|
75
|
+
SPEC.md # Local-prep / cloud-authority protocol
|
|
76
|
+
THREAT_MODEL.md # Assumptions, non-goals, failure modes
|
|
77
|
+
docs/measured-exposure.md # Evidence-backed exposure report shape
|
|
78
|
+
docs/telemetry.md # Metadata-only packet telemetry contract
|
|
79
|
+
docs/side-effect-review.md # Authority-side side-effect review records
|
|
80
|
+
docs/policy.md # Policy-origin validation and exposure/side-effect gates
|
|
81
|
+
docs/operations.md # Guardrail events and lane health records
|
|
82
|
+
docs/broker-decision.md # Metadata-only execution broker decision packets
|
|
83
|
+
docs/protocol-not-gateway.md # Why this is a protocol, not a gateway
|
|
84
|
+
docs/public-private-boundary.md # What belongs in public vs private implementations
|
|
85
|
+
docs/current-router-compatibility.md # Current Hermes local-router adapter boundary
|
|
86
|
+
docs/release-checklist.md # v0.1.0 package/release checklist
|
|
87
|
+
schemas/ # Language-agnostic JSON Schema contracts
|
|
88
|
+
src/sovereignty/ # Reference Python implementation
|
|
89
|
+
examples/hermes/ # Hermes local-router adapter examples
|
|
90
|
+
tests/ # Contract tests
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Design principles
|
|
94
|
+
|
|
95
|
+
1. Local models can prepare. They do not decide.
|
|
96
|
+
2. Side effects require main-agent or human authority.
|
|
97
|
+
3. Exposure accounting must state whether it is measured or caller-attested.
|
|
98
|
+
4. Review packets are structured, versioned, and validated.
|
|
99
|
+
5. Privacy/security claims should be falsifiable, not vibes.
|
|
100
|
+
|
|
101
|
+
## First public proof
|
|
102
|
+
|
|
103
|
+
The v0.1 proof is intentionally narrow: a local lane reads raw diagnostic context, emits a compact `ReviewPacket`, attaches measured exposure evidence, and proposes a side effect that remains review-only until the authority-bearing agent acts.
|
|
104
|
+
|
|
105
|
+
Run it from a checkout:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
PYTHONPATH=src .venv/bin/python examples/hermes/local_router_review_packet.py
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
What to look for in the JSON output:
|
|
112
|
+
|
|
113
|
+
- `review_packet.local_output` contains the compact local summary, not the raw incident text.
|
|
114
|
+
- `review_packet.model_metadata` keeps sanitized `worker_profile`, `model_used`, and `lane_model_map` fields, without base URLs, host paths, or tokens.
|
|
115
|
+
- `review_packet.exposure.trust_model` is `measured`, and the attached `measured_exposure_report` avoids raw request bodies.
|
|
116
|
+
- `packet_telemetry.token_accounting` separates estimated local/input/output counts from exposed-to-cloud counts.
|
|
117
|
+
- `current_router_compatibility.actual_avoided_cloud_tokens` is only claimed for the pre-cloud/local-ingress shape where `raw_context_seen_by_cloud=false`.
|
|
118
|
+
- Side effects are proposals only; the local lane cannot create issues, send messages, publish, deploy, trade, pay, or order.
|
|
119
|
+
|
|
120
|
+
That is the positioning wedge: LiteLLM, Portkey, and RouteLLM are useful gateway/routing layers; Sovereignty is the local-prep / cloud-authority contract around what local workers may prepare, what evidence crosses the boundary, and who is allowed to act.
|
|
121
|
+
|
|
122
|
+
## Quick start
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
python3 -m venv .venv
|
|
126
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
127
|
+
.venv/bin/python -m pip install -e '.[dev]'
|
|
128
|
+
.venv/bin/python -m pytest tests -q
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The PyPI distribution name is `sovereignty-protocol` because `sovereignty` is already taken on PyPI. The import package and CLI command remain `sovereignty`.
|
|
132
|
+
|
|
133
|
+
Install from a local checkout:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
python3 -m pip install -e .
|
|
137
|
+
sovereignty --help
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Create a basic review packet:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
.venv/bin/python examples/basic_packet.py
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Run the measured-exposure recording boundary example:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
.venv/bin/python examples/recording_boundary.py
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Run the Hermes local-router integration example:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
PYTHONPATH=src .venv/bin/python examples/hermes/local_router_review_packet.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The local-router integration demonstrates a local prep lane producing a review packet with measured exposure evidence, metadata-only packet telemetry, and a review-only side-effect proposal for the main Hermes agent.
|
|
159
|
+
|
|
160
|
+
Validate a packet JSON file:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
sovereignty validate packet.json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Redact model metadata:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
sovereignty redact metadata.json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## CLI
|
|
173
|
+
|
|
174
|
+
Sovereignty's first CLI commands are protocol utilities, not router commands:
|
|
175
|
+
|
|
176
|
+
- `validate packet.json` validates a review packet and returns a JSON status object.
|
|
177
|
+
- `redact metadata.json` removes secrets, host-local URLs, and private paths from model metadata.
|
|
178
|
+
|
|
179
|
+
## JSON Schema contracts
|
|
180
|
+
|
|
181
|
+
Language-agnostic schemas live in `schemas/`:
|
|
182
|
+
|
|
183
|
+
- `schemas/review-packet.schema.json`
|
|
184
|
+
- `schemas/exposure.schema.json`
|
|
185
|
+
- `schemas/measured-exposure-report.schema.json`
|
|
186
|
+
- `schemas/side-effect-proposal.schema.json`
|
|
187
|
+
- `schemas/packet-telemetry.schema.json`
|
|
188
|
+
- `schemas/side-effect-review-record.schema.json`
|
|
189
|
+
- `schemas/policy.schema.json`
|
|
190
|
+
- `schemas/guardrail-event.schema.json`
|
|
191
|
+
- `schemas/lane-health.schema.json`
|
|
192
|
+
- `schemas/exposure-budget.schema.json`
|
|
193
|
+
- `schemas/broker-decision.schema.json`
|
|
194
|
+
|
|
195
|
+
These schemas mirror the v0.1 protocol surface for non-Python validators and integrations. Packet telemetry is documented in `docs/telemetry.md` and is metadata-only by default. Side-effect review records are documented in `docs/side-effect-review.md` and remain separate from local-lane side-effect proposals. Policy-origin validation and exposure budgets are documented in `docs/policy.md`. Guardrail events and lane health are documented in `docs/operations.md`. Broker decisions are documented in `docs/broker-decision.md`; the public/private boundary is documented in `docs/public-private-boundary.md`.
|
|
196
|
+
|
|
197
|
+
## Release path
|
|
198
|
+
|
|
199
|
+
The v0.1.0 release checklist lives at `docs/release-checklist.md`. `python -m build` is part of CI, and the package is published under the distribution name `sovereignty-protocol` while preserving the `sovereignty` import package and CLI.
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
Apache-2.0. Sovereignty is intended to remain open source.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Sovereignty
|
|
2
|
+
|
|
3
|
+
```text
|
|
4
|
+
.-.
|
|
5
|
+
/___\
|
|
6
|
+
(|o o|)
|
|
7
|
+
.--.\_-_/ .--.
|
|
8
|
+
/ _ '-' _ \
|
|
9
|
+
/__/ | | \__\
|
|
10
|
+
| | | | | |
|
|
11
|
+
|__| |_____| |__|
|
|
12
|
+
/ | \
|
|
13
|
+
/___|___\
|
|
14
|
+
|
|
15
|
+
______ _ __
|
|
16
|
+
/ ___/ /___ _ _____ ________ (_)___ _____ / /___ __
|
|
17
|
+
\__ \/ __ \ | / / _ \/ ___/ _ \/ / __ `/ __ \/ __/ / / /
|
|
18
|
+
___/ / /_/ / |/ / __/ / / __/ / /_/ / / / / /_/ /_/ /
|
|
19
|
+
/____/\____/|___/\___/_/ \___/_/\__, /_/ /_/\__/\__, /
|
|
20
|
+
/____/ /____/
|
|
21
|
+
|
|
22
|
+
local models do the prep. your agent keeps authority.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Sovereignty is an open-source protocol and reference implementation for local-first agent delegation. It defines how local model lanes can perform private prep work — classification, extraction, drafting, code triage, and sensitivity checks — while a main agent retains authority over final answers and side effects.
|
|
26
|
+
|
|
27
|
+
Sovereignty is not an LLM gateway. It is a contract for local-prep / cloud-authority workflows; see `docs/protocol-not-gateway.md` for the design note on why this is a protocol, not a gateway:
|
|
28
|
+
|
|
29
|
+
- local lanes produce structured review packets;
|
|
30
|
+
- local lanes do not invoke side-effecting tools;
|
|
31
|
+
- model and lane metadata is redacted before it leaves the local boundary;
|
|
32
|
+
- cloud exposure claims are explicit about their trust model;
|
|
33
|
+
- measured exposure reports can attach evidence without leaking raw prompts or endpoints;
|
|
34
|
+
- proposed side effects use a strict review-only schema before any authority-bearing tool acts;
|
|
35
|
+
- callers can validate packets and policies before a main agent acts.
|
|
36
|
+
|
|
37
|
+
## Status
|
|
38
|
+
|
|
39
|
+
v0.1.0 protocol release. The public surface is intentionally small and falsifiable: schema contracts, policy checks, metadata redaction, measured exposure reporting, side-effect review boundaries, a sober threat model, and Hermes adapter examples.
|
|
40
|
+
|
|
41
|
+
Sovereignty is still not a router or gateway. The private router implementation can evolve independently; this repository publishes the boundary contract local-prep systems must satisfy before an authority-bearing agent acts.
|
|
42
|
+
|
|
43
|
+
## Repository layout
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
sovereignty/
|
|
47
|
+
SPEC.md # Local-prep / cloud-authority protocol
|
|
48
|
+
THREAT_MODEL.md # Assumptions, non-goals, failure modes
|
|
49
|
+
docs/measured-exposure.md # Evidence-backed exposure report shape
|
|
50
|
+
docs/telemetry.md # Metadata-only packet telemetry contract
|
|
51
|
+
docs/side-effect-review.md # Authority-side side-effect review records
|
|
52
|
+
docs/policy.md # Policy-origin validation and exposure/side-effect gates
|
|
53
|
+
docs/operations.md # Guardrail events and lane health records
|
|
54
|
+
docs/broker-decision.md # Metadata-only execution broker decision packets
|
|
55
|
+
docs/protocol-not-gateway.md # Why this is a protocol, not a gateway
|
|
56
|
+
docs/public-private-boundary.md # What belongs in public vs private implementations
|
|
57
|
+
docs/current-router-compatibility.md # Current Hermes local-router adapter boundary
|
|
58
|
+
docs/release-checklist.md # v0.1.0 package/release checklist
|
|
59
|
+
schemas/ # Language-agnostic JSON Schema contracts
|
|
60
|
+
src/sovereignty/ # Reference Python implementation
|
|
61
|
+
examples/hermes/ # Hermes local-router adapter examples
|
|
62
|
+
tests/ # Contract tests
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Design principles
|
|
66
|
+
|
|
67
|
+
1. Local models can prepare. They do not decide.
|
|
68
|
+
2. Side effects require main-agent or human authority.
|
|
69
|
+
3. Exposure accounting must state whether it is measured or caller-attested.
|
|
70
|
+
4. Review packets are structured, versioned, and validated.
|
|
71
|
+
5. Privacy/security claims should be falsifiable, not vibes.
|
|
72
|
+
|
|
73
|
+
## First public proof
|
|
74
|
+
|
|
75
|
+
The v0.1 proof is intentionally narrow: a local lane reads raw diagnostic context, emits a compact `ReviewPacket`, attaches measured exposure evidence, and proposes a side effect that remains review-only until the authority-bearing agent acts.
|
|
76
|
+
|
|
77
|
+
Run it from a checkout:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
PYTHONPATH=src .venv/bin/python examples/hermes/local_router_review_packet.py
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
What to look for in the JSON output:
|
|
84
|
+
|
|
85
|
+
- `review_packet.local_output` contains the compact local summary, not the raw incident text.
|
|
86
|
+
- `review_packet.model_metadata` keeps sanitized `worker_profile`, `model_used`, and `lane_model_map` fields, without base URLs, host paths, or tokens.
|
|
87
|
+
- `review_packet.exposure.trust_model` is `measured`, and the attached `measured_exposure_report` avoids raw request bodies.
|
|
88
|
+
- `packet_telemetry.token_accounting` separates estimated local/input/output counts from exposed-to-cloud counts.
|
|
89
|
+
- `current_router_compatibility.actual_avoided_cloud_tokens` is only claimed for the pre-cloud/local-ingress shape where `raw_context_seen_by_cloud=false`.
|
|
90
|
+
- Side effects are proposals only; the local lane cannot create issues, send messages, publish, deploy, trade, pay, or order.
|
|
91
|
+
|
|
92
|
+
That is the positioning wedge: LiteLLM, Portkey, and RouteLLM are useful gateway/routing layers; Sovereignty is the local-prep / cloud-authority contract around what local workers may prepare, what evidence crosses the boundary, and who is allowed to act.
|
|
93
|
+
|
|
94
|
+
## Quick start
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python3 -m venv .venv
|
|
98
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
99
|
+
.venv/bin/python -m pip install -e '.[dev]'
|
|
100
|
+
.venv/bin/python -m pytest tests -q
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The PyPI distribution name is `sovereignty-protocol` because `sovereignty` is already taken on PyPI. The import package and CLI command remain `sovereignty`.
|
|
104
|
+
|
|
105
|
+
Install from a local checkout:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
python3 -m pip install -e .
|
|
109
|
+
sovereignty --help
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Create a basic review packet:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
.venv/bin/python examples/basic_packet.py
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Run the measured-exposure recording boundary example:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
.venv/bin/python examples/recording_boundary.py
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Run the Hermes local-router integration example:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
PYTHONPATH=src .venv/bin/python examples/hermes/local_router_review_packet.py
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The local-router integration demonstrates a local prep lane producing a review packet with measured exposure evidence, metadata-only packet telemetry, and a review-only side-effect proposal for the main Hermes agent.
|
|
131
|
+
|
|
132
|
+
Validate a packet JSON file:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
sovereignty validate packet.json
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Redact model metadata:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
sovereignty redact metadata.json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## CLI
|
|
145
|
+
|
|
146
|
+
Sovereignty's first CLI commands are protocol utilities, not router commands:
|
|
147
|
+
|
|
148
|
+
- `validate packet.json` validates a review packet and returns a JSON status object.
|
|
149
|
+
- `redact metadata.json` removes secrets, host-local URLs, and private paths from model metadata.
|
|
150
|
+
|
|
151
|
+
## JSON Schema contracts
|
|
152
|
+
|
|
153
|
+
Language-agnostic schemas live in `schemas/`:
|
|
154
|
+
|
|
155
|
+
- `schemas/review-packet.schema.json`
|
|
156
|
+
- `schemas/exposure.schema.json`
|
|
157
|
+
- `schemas/measured-exposure-report.schema.json`
|
|
158
|
+
- `schemas/side-effect-proposal.schema.json`
|
|
159
|
+
- `schemas/packet-telemetry.schema.json`
|
|
160
|
+
- `schemas/side-effect-review-record.schema.json`
|
|
161
|
+
- `schemas/policy.schema.json`
|
|
162
|
+
- `schemas/guardrail-event.schema.json`
|
|
163
|
+
- `schemas/lane-health.schema.json`
|
|
164
|
+
- `schemas/exposure-budget.schema.json`
|
|
165
|
+
- `schemas/broker-decision.schema.json`
|
|
166
|
+
|
|
167
|
+
These schemas mirror the v0.1 protocol surface for non-Python validators and integrations. Packet telemetry is documented in `docs/telemetry.md` and is metadata-only by default. Side-effect review records are documented in `docs/side-effect-review.md` and remain separate from local-lane side-effect proposals. Policy-origin validation and exposure budgets are documented in `docs/policy.md`. Guardrail events and lane health are documented in `docs/operations.md`. Broker decisions are documented in `docs/broker-decision.md`; the public/private boundary is documented in `docs/public-private-boundary.md`.
|
|
168
|
+
|
|
169
|
+
## Release path
|
|
170
|
+
|
|
171
|
+
The v0.1.0 release checklist lives at `docs/release-checklist.md`. `python -m build` is part of CI, and the package is published under the distribution name `sovereignty-protocol` while preserving the `sovereignty` import package and CLI.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
Apache-2.0. Sovereignty is intended to remain open source.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sovereignty-protocol"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Local-first agent delegation protocol and reference implementation"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
authors = [{name = "Sovereignty contributors"}]
|
|
13
|
+
keywords = ["agents", "local-first", "llm", "privacy", "protocol", "router"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
21
|
+
"Topic :: Security",
|
|
22
|
+
"Typing :: Typed",
|
|
23
|
+
]
|
|
24
|
+
dependencies = []
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
dev = ["pytest>=8.0", "jsonschema>=4.0", "build>=1.0", "twine>=5.0"]
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
sovereignty = "sovereignty.__main__:main"
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/m0ntydad0n/sovereignty"
|
|
34
|
+
Repository = "https://github.com/m0ntydad0n/sovereignty"
|
|
35
|
+
Issues = "https://github.com/m0ntydad0n/sovereignty/issues"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.package-data]
|
|
41
|
+
sovereignty = ["py.typed"]
|
|
42
|
+
|
|
43
|
+
[tool.pytest.ini_options]
|
|
44
|
+
pythonpath = ["src"]
|
|
45
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
2
|
+
|
|
3
|
+
from .exposure import Exposure
|
|
4
|
+
from .exposure_budget import ExposureBudget
|
|
5
|
+
from .guardrails import GuardrailEvent, validate_guardrail_event
|
|
6
|
+
from .lane_health import LaneHealth, validate_lane_health
|
|
7
|
+
from .measured_exposure import (
|
|
8
|
+
RecordedRequest,
|
|
9
|
+
RecordingBoundary,
|
|
10
|
+
build_measured_exposure_report,
|
|
11
|
+
)
|
|
12
|
+
from .packet import ReviewPacket, validate_packet, validate_packet_dict
|
|
13
|
+
from .policy import SovereigntyPolicy, SovereigntyPolicyError
|
|
14
|
+
from .redaction import redact_model_metadata
|
|
15
|
+
from .side_effect_review import SideEffectReviewRecord, validate_side_effect_review_record
|
|
16
|
+
from .side_effects import SideEffectProposal, validate_side_effect_proposal
|
|
17
|
+
from .telemetry import PacketTelemetry, build_error_digest, validate_packet_telemetry
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"__version__",
|
|
21
|
+
"Exposure",
|
|
22
|
+
"ExposureBudget",
|
|
23
|
+
"GuardrailEvent",
|
|
24
|
+
"LaneHealth",
|
|
25
|
+
"RecordedRequest",
|
|
26
|
+
"RecordingBoundary",
|
|
27
|
+
"ReviewPacket",
|
|
28
|
+
"SideEffectProposal",
|
|
29
|
+
"SideEffectReviewRecord",
|
|
30
|
+
"PacketTelemetry",
|
|
31
|
+
"SovereigntyPolicyError",
|
|
32
|
+
"SovereigntyPolicy",
|
|
33
|
+
"build_error_digest",
|
|
34
|
+
"build_measured_exposure_report",
|
|
35
|
+
"redact_model_metadata",
|
|
36
|
+
"validate_guardrail_event",
|
|
37
|
+
"validate_lane_health",
|
|
38
|
+
"validate_packet",
|
|
39
|
+
"validate_packet_dict",
|
|
40
|
+
"validate_packet_telemetry",
|
|
41
|
+
"validate_side_effect_proposal",
|
|
42
|
+
"validate_side_effect_review_record",
|
|
43
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from .packet import validate_packet_dict
|
|
10
|
+
from .policy import SovereigntyPolicyError
|
|
11
|
+
from .redaction import redact_model_metadata
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main(argv: list[str] | None = None) -> int:
|
|
15
|
+
parser = argparse.ArgumentParser(prog="sovereignty")
|
|
16
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
17
|
+
|
|
18
|
+
validate_parser = subparsers.add_parser("validate", help="Validate a review packet JSON file")
|
|
19
|
+
validate_parser.add_argument("path", help="Path to packet JSON")
|
|
20
|
+
|
|
21
|
+
redact_parser = subparsers.add_parser("redact", help="Redact model metadata JSON")
|
|
22
|
+
redact_parser.add_argument("path", help="Path to metadata JSON")
|
|
23
|
+
|
|
24
|
+
args = parser.parse_args(argv)
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
data = _read_json(args.path)
|
|
28
|
+
if args.command == "validate":
|
|
29
|
+
packet = validate_packet_dict(data)
|
|
30
|
+
_print_json({"ok": True, "packet": packet.to_dict()})
|
|
31
|
+
return 0
|
|
32
|
+
if args.command == "redact":
|
|
33
|
+
_print_json(redact_model_metadata(data))
|
|
34
|
+
return 0
|
|
35
|
+
except (OSError, json.JSONDecodeError, SovereigntyPolicyError, TypeError) as exc:
|
|
36
|
+
_print_json({"ok": False, "error": str(exc)})
|
|
37
|
+
return 1
|
|
38
|
+
|
|
39
|
+
_print_json({"ok": False, "error": f"unsupported command: {args.command}"})
|
|
40
|
+
return 1
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _read_json(path: str) -> Any:
|
|
44
|
+
return json.loads(Path(path).read_text())
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _print_json(payload: Any) -> None:
|
|
48
|
+
print(json.dumps(payload, sort_keys=True))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
if __name__ == "__main__":
|
|
52
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from .policy import SovereigntyPolicyError
|
|
6
|
+
|
|
7
|
+
EXPOSURE_CLASSIFICATIONS = {"raw", "excerpt", "summary", "none", "unknown"}
|
|
8
|
+
EXPOSURE_TRUST_MODELS = {"caller_attested", "measured", "not_applicable"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class Exposure:
|
|
13
|
+
classification: str
|
|
14
|
+
trust_model: str
|
|
15
|
+
evidence: str | None = None
|
|
16
|
+
|
|
17
|
+
def __post_init__(self) -> None:
|
|
18
|
+
if self.classification not in EXPOSURE_CLASSIFICATIONS:
|
|
19
|
+
raise SovereigntyPolicyError(
|
|
20
|
+
f"unsupported exposure classification: {self.classification}"
|
|
21
|
+
)
|
|
22
|
+
if self.trust_model not in EXPOSURE_TRUST_MODELS:
|
|
23
|
+
raise SovereigntyPolicyError(
|
|
24
|
+
f"unsupported exposure trust_model: {self.trust_model}"
|
|
25
|
+
)
|
|
26
|
+
if self.trust_model == "measured" and not self.evidence:
|
|
27
|
+
raise SovereigntyPolicyError("measured exposure requires evidence")
|