sovereign-sdk-ledger 1.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.
- sovereign_sdk_ledger-1.3.0/PKG-INFO +197 -0
- sovereign_sdk_ledger-1.3.0/README.md +180 -0
- sovereign_sdk_ledger-1.3.0/pyproject.toml +27 -0
- sovereign_sdk_ledger-1.3.0/setup.cfg +4 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_ledger/__init__.py +17 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_ledger/engine.py +545 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_sdk_ledger.egg-info/PKG-INFO +197 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_sdk_ledger.egg-info/SOURCES.txt +9 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_sdk_ledger.egg-info/dependency_links.txt +1 -0
- sovereign_sdk_ledger-1.3.0/src/sovereign_sdk_ledger.egg-info/top_level.txt +1 -0
- sovereign_sdk_ledger-1.3.0/tests/test_ledger.py +1138 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sovereign-sdk-ledger
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Immutable, local-first, hash-chained SQLite provenance engine for ForensicReceipt Write-Side Custody
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/kenwalger/sovereign-sdk
|
|
7
|
+
Project-URL: Repository, https://github.com/kenwalger/sovereign-sdk
|
|
8
|
+
Project-URL: Changelog, https://github.com/kenwalger/sovereign-sdk/blob/main/CHANGELOG.md
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Security
|
|
13
|
+
Classifier: Topic :: Database
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# sovereign-ledger
|
|
19
|
+
|
|
20
|
+
**Immutable, local-first, hash-chained SQLite provenance engine for ForensicReceipt Write-Side Custody.**
|
|
21
|
+
|
|
22
|
+
`sovereign-ledger` is a zero-external-dependency Python package that stores every
|
|
23
|
+
`ForensicReceipt` produced by `sovereign-core` in a tamper-evident, append-only SQLite
|
|
24
|
+
database. It enforces Write-Side Custody through two complementary mechanisms: engine-level
|
|
25
|
+
SQL triggers that abort any `UPDATE` or `DELETE` at the SQLite layer, and a SHA-256 hash
|
|
26
|
+
chain that makes out-of-band filesystem tampering mathematically detectable.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install sovereign-sdk-ledger
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Requires Python 3.12 or later. Zero runtime dependencies beyond the Python standard library.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from sovereign_ledger import SovereignLedger
|
|
44
|
+
|
|
45
|
+
# Open (or create) the audit database
|
|
46
|
+
with SovereignLedger(db_path=".keys/sovereign_audit.db") as ledger:
|
|
47
|
+
|
|
48
|
+
# Append a signed ForensicReceipt after a sieve-and-sign pass
|
|
49
|
+
tip = ledger.append_receipt(receipt, sieved_content)
|
|
50
|
+
|
|
51
|
+
# Verify the full hash chain at any time
|
|
52
|
+
assert ledger.verify_ledger_integrity() # True on an untampered ledger
|
|
53
|
+
|
|
54
|
+
# Pin the sweep to a known tip to detect tail-truncation attacks
|
|
55
|
+
assert ledger.verify_ledger_integrity(expected_tip_hash=tip) # False if last row was deleted
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## API reference
|
|
61
|
+
|
|
62
|
+
### `SovereignLedger(db_path=".keys/sovereign_audit.db")`
|
|
63
|
+
|
|
64
|
+
Opens the SQLite database at `db_path`, applies WAL journal mode, `NORMAL` synchronous
|
|
65
|
+
enforcement, and strict foreign-key constraints, then bootstraps the `forensic_ledger`
|
|
66
|
+
schema and Write-Side Custody triggers if they do not already exist. Pass `":memory:"` for
|
|
67
|
+
an ephemeral in-process store.
|
|
68
|
+
|
|
69
|
+
Supports the Python context manager protocol — use a `with` block to guarantee all
|
|
70
|
+
thread-local connection handles are released on exit.
|
|
71
|
+
|
|
72
|
+
### `append_receipt(receipt: dict, sieved_content: str) -> str`
|
|
73
|
+
|
|
74
|
+
Derives a rolling SHA-256 `parent_hash` from the immediately preceding row's full
|
|
75
|
+
eight-column canonical preimage (or from the static genesis constant for the first entry)
|
|
76
|
+
and inserts an immutable row inside a `BEGIN IMMEDIATE` transaction. Returns the
|
|
77
|
+
`payload_hash` as an opaque receipt identifier.
|
|
78
|
+
|
|
79
|
+
Raises `sqlite3.IntegrityError` if `receipt["payload_hash"]` is already present (UNIQUE
|
|
80
|
+
constraint). Raises `sqlite3.OperationalError` if the database lock cannot be acquired
|
|
81
|
+
within the configured 5-second `busy_timeout`.
|
|
82
|
+
|
|
83
|
+
### `verify_ledger_integrity(expected_tip_hash=None) -> bool`
|
|
84
|
+
|
|
85
|
+
Performs an O(n) streaming cursor sweep, re-deriving the expected `parent_hash` for every
|
|
86
|
+
row from its predecessor. Returns `True` if every entry is intact; `False` on the first
|
|
87
|
+
detected breach.
|
|
88
|
+
|
|
89
|
+
If `expected_tip_hash` is supplied, the sweep additionally asserts that the `payload_hash`
|
|
90
|
+
of the final ledger row matches the provided anchor, closing the tail-truncation blind spot
|
|
91
|
+
where an adversary drops the `BEFORE DELETE` trigger and removes trailing rows that leave
|
|
92
|
+
the surviving prefix chain internally consistent.
|
|
93
|
+
|
|
94
|
+
### `close()`
|
|
95
|
+
|
|
96
|
+
Releases all thread-local SQLite connection handles tracked by this instance. The closed
|
|
97
|
+
flag is set atomically inside the connection-registry lock so that any concurrent thread
|
|
98
|
+
attempting `_get_conn()` after teardown receives a `SovereignStorageError` rather than
|
|
99
|
+
a leaked or dangling connection handle.
|
|
100
|
+
|
|
101
|
+
### `SovereignStorageError`
|
|
102
|
+
|
|
103
|
+
`RuntimeError` subclass raised when any ledger operation is attempted on an instance that
|
|
104
|
+
has been explicitly closed. Import alongside `SovereignLedger`:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from sovereign_ledger import SovereignLedger, SovereignStorageError
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Cryptographic invariants
|
|
113
|
+
|
|
114
|
+
### Write-Side Custody triggers
|
|
115
|
+
|
|
116
|
+
Two `BEFORE UPDATE` and `BEFORE DELETE` SQL triggers are stored inside the `.db` file
|
|
117
|
+
itself:
|
|
118
|
+
|
|
119
|
+
```sql
|
|
120
|
+
CREATE TRIGGER prevent_update_forensic_ledger
|
|
121
|
+
BEFORE UPDATE ON forensic_ledger
|
|
122
|
+
BEGIN
|
|
123
|
+
SELECT RAISE(ROLLBACK, 'Write-Side Custody violation: UPDATE operations are prohibited on forensic_ledger.');
|
|
124
|
+
END;
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Any client that opens the file — Python code, a desktop SQL browser, a raw
|
|
128
|
+
`sqlite3.connect()` call — receives a `sqlite3.IntegrityError` and has its entire
|
|
129
|
+
enclosing transaction rolled back at the SQLite engine layer before any mutation lands.
|
|
130
|
+
|
|
131
|
+
### SHA-256 hash chain
|
|
132
|
+
|
|
133
|
+
Each row stores a `parent_hash` field that is the SHA-256 digest of the immediately
|
|
134
|
+
preceding row's complete eight-column canonical preimage, assembled with a NUL byte
|
|
135
|
+
(`\x00`) delimiter between every field:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
parent_hash[N] = SHA-256(
|
|
139
|
+
"\x00".join([
|
|
140
|
+
row[N-1].signature,
|
|
141
|
+
row[N-1].payload_hash,
|
|
142
|
+
row[N-1].parent_hash,
|
|
143
|
+
row[N-1].timestamp,
|
|
144
|
+
str(row[N-1].raw_token_count), # "NULL" when NULL
|
|
145
|
+
str(row[N-1].optimized_token_count), # "NULL" when NULL
|
|
146
|
+
f"{float(row[N-1].tax_savings_percentage):.4f}", # "NULL" when NULL
|
|
147
|
+
row[N-1].sieved_content,
|
|
148
|
+
])
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The NUL delimiter closes length-substitution field-boundary attacks. Fixed-precision
|
|
153
|
+
`:.4f` serialisation for `tax_savings_percentage` ensures that a Python `int` supplied at
|
|
154
|
+
append time and a SQLite `REAL` extracted at verification time both produce the identical
|
|
155
|
+
canonical token, preventing silent chain divergence.
|
|
156
|
+
|
|
157
|
+
Any out-of-band mutation of any stored value — textual payload, ingestion timestamp,
|
|
158
|
+
FinOps telemetry, or cryptographic fields — immediately breaks the chain and is detected
|
|
159
|
+
by `verify_ledger_integrity()`.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Thread safety
|
|
164
|
+
|
|
165
|
+
Each thread that accesses a shared `SovereignLedger` instance receives its own isolated
|
|
166
|
+
`sqlite3.Connection` via the internal `_get_conn()` method. `BEGIN IMMEDIATE` and a
|
|
167
|
+
5-second `busy_timeout` serialise writes at the SQLite reserved-lock level, preventing
|
|
168
|
+
sibling-fork `parent_hash` collisions without requiring a Python-layer mutex.
|
|
169
|
+
|
|
170
|
+
The closed-state flag is set atomically inside the connection-registry lock during
|
|
171
|
+
`close()`, eliminating the race window where a thread could slip past the guard and
|
|
172
|
+
register a dangling connection handle after teardown.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Integration pattern
|
|
177
|
+
|
|
178
|
+
`sovereign-ledger` slots into the end of the Sovereign pipeline:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
[Inbound Payload]
|
|
182
|
+
→ sovereign-sieve (Prose Tax reduction)
|
|
183
|
+
→ sovereign-core (Ed25519 sign → ForensicReceipt)
|
|
184
|
+
→ sovereign-ledger (append_receipt → immutable audit record)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from sovereign_core import SovereignGateway
|
|
189
|
+
from sovereign_ledger import SovereignLedger
|
|
190
|
+
|
|
191
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
192
|
+
|
|
193
|
+
with SovereignLedger(db_path=".keys/sovereign_audit.db") as ledger:
|
|
194
|
+
response = await gateway.sieve_and_sign(raw_payload)
|
|
195
|
+
tip = ledger.append_receipt(response.receipt, response.content)
|
|
196
|
+
assert ledger.verify_ledger_integrity(expected_tip_hash=tip)
|
|
197
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# sovereign-ledger
|
|
2
|
+
|
|
3
|
+
**Immutable, local-first, hash-chained SQLite provenance engine for ForensicReceipt Write-Side Custody.**
|
|
4
|
+
|
|
5
|
+
`sovereign-ledger` is a zero-external-dependency Python package that stores every
|
|
6
|
+
`ForensicReceipt` produced by `sovereign-core` in a tamper-evident, append-only SQLite
|
|
7
|
+
database. It enforces Write-Side Custody through two complementary mechanisms: engine-level
|
|
8
|
+
SQL triggers that abort any `UPDATE` or `DELETE` at the SQLite layer, and a SHA-256 hash
|
|
9
|
+
chain that makes out-of-band filesystem tampering mathematically detectable.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install sovereign-sdk-ledger
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Requires Python 3.12 or later. Zero runtime dependencies beyond the Python standard library.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from sovereign_ledger import SovereignLedger
|
|
27
|
+
|
|
28
|
+
# Open (or create) the audit database
|
|
29
|
+
with SovereignLedger(db_path=".keys/sovereign_audit.db") as ledger:
|
|
30
|
+
|
|
31
|
+
# Append a signed ForensicReceipt after a sieve-and-sign pass
|
|
32
|
+
tip = ledger.append_receipt(receipt, sieved_content)
|
|
33
|
+
|
|
34
|
+
# Verify the full hash chain at any time
|
|
35
|
+
assert ledger.verify_ledger_integrity() # True on an untampered ledger
|
|
36
|
+
|
|
37
|
+
# Pin the sweep to a known tip to detect tail-truncation attacks
|
|
38
|
+
assert ledger.verify_ledger_integrity(expected_tip_hash=tip) # False if last row was deleted
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## API reference
|
|
44
|
+
|
|
45
|
+
### `SovereignLedger(db_path=".keys/sovereign_audit.db")`
|
|
46
|
+
|
|
47
|
+
Opens the SQLite database at `db_path`, applies WAL journal mode, `NORMAL` synchronous
|
|
48
|
+
enforcement, and strict foreign-key constraints, then bootstraps the `forensic_ledger`
|
|
49
|
+
schema and Write-Side Custody triggers if they do not already exist. Pass `":memory:"` for
|
|
50
|
+
an ephemeral in-process store.
|
|
51
|
+
|
|
52
|
+
Supports the Python context manager protocol — use a `with` block to guarantee all
|
|
53
|
+
thread-local connection handles are released on exit.
|
|
54
|
+
|
|
55
|
+
### `append_receipt(receipt: dict, sieved_content: str) -> str`
|
|
56
|
+
|
|
57
|
+
Derives a rolling SHA-256 `parent_hash` from the immediately preceding row's full
|
|
58
|
+
eight-column canonical preimage (or from the static genesis constant for the first entry)
|
|
59
|
+
and inserts an immutable row inside a `BEGIN IMMEDIATE` transaction. Returns the
|
|
60
|
+
`payload_hash` as an opaque receipt identifier.
|
|
61
|
+
|
|
62
|
+
Raises `sqlite3.IntegrityError` if `receipt["payload_hash"]` is already present (UNIQUE
|
|
63
|
+
constraint). Raises `sqlite3.OperationalError` if the database lock cannot be acquired
|
|
64
|
+
within the configured 5-second `busy_timeout`.
|
|
65
|
+
|
|
66
|
+
### `verify_ledger_integrity(expected_tip_hash=None) -> bool`
|
|
67
|
+
|
|
68
|
+
Performs an O(n) streaming cursor sweep, re-deriving the expected `parent_hash` for every
|
|
69
|
+
row from its predecessor. Returns `True` if every entry is intact; `False` on the first
|
|
70
|
+
detected breach.
|
|
71
|
+
|
|
72
|
+
If `expected_tip_hash` is supplied, the sweep additionally asserts that the `payload_hash`
|
|
73
|
+
of the final ledger row matches the provided anchor, closing the tail-truncation blind spot
|
|
74
|
+
where an adversary drops the `BEFORE DELETE` trigger and removes trailing rows that leave
|
|
75
|
+
the surviving prefix chain internally consistent.
|
|
76
|
+
|
|
77
|
+
### `close()`
|
|
78
|
+
|
|
79
|
+
Releases all thread-local SQLite connection handles tracked by this instance. The closed
|
|
80
|
+
flag is set atomically inside the connection-registry lock so that any concurrent thread
|
|
81
|
+
attempting `_get_conn()` after teardown receives a `SovereignStorageError` rather than
|
|
82
|
+
a leaked or dangling connection handle.
|
|
83
|
+
|
|
84
|
+
### `SovereignStorageError`
|
|
85
|
+
|
|
86
|
+
`RuntimeError` subclass raised when any ledger operation is attempted on an instance that
|
|
87
|
+
has been explicitly closed. Import alongside `SovereignLedger`:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from sovereign_ledger import SovereignLedger, SovereignStorageError
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Cryptographic invariants
|
|
96
|
+
|
|
97
|
+
### Write-Side Custody triggers
|
|
98
|
+
|
|
99
|
+
Two `BEFORE UPDATE` and `BEFORE DELETE` SQL triggers are stored inside the `.db` file
|
|
100
|
+
itself:
|
|
101
|
+
|
|
102
|
+
```sql
|
|
103
|
+
CREATE TRIGGER prevent_update_forensic_ledger
|
|
104
|
+
BEFORE UPDATE ON forensic_ledger
|
|
105
|
+
BEGIN
|
|
106
|
+
SELECT RAISE(ROLLBACK, 'Write-Side Custody violation: UPDATE operations are prohibited on forensic_ledger.');
|
|
107
|
+
END;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Any client that opens the file — Python code, a desktop SQL browser, a raw
|
|
111
|
+
`sqlite3.connect()` call — receives a `sqlite3.IntegrityError` and has its entire
|
|
112
|
+
enclosing transaction rolled back at the SQLite engine layer before any mutation lands.
|
|
113
|
+
|
|
114
|
+
### SHA-256 hash chain
|
|
115
|
+
|
|
116
|
+
Each row stores a `parent_hash` field that is the SHA-256 digest of the immediately
|
|
117
|
+
preceding row's complete eight-column canonical preimage, assembled with a NUL byte
|
|
118
|
+
(`\x00`) delimiter between every field:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
parent_hash[N] = SHA-256(
|
|
122
|
+
"\x00".join([
|
|
123
|
+
row[N-1].signature,
|
|
124
|
+
row[N-1].payload_hash,
|
|
125
|
+
row[N-1].parent_hash,
|
|
126
|
+
row[N-1].timestamp,
|
|
127
|
+
str(row[N-1].raw_token_count), # "NULL" when NULL
|
|
128
|
+
str(row[N-1].optimized_token_count), # "NULL" when NULL
|
|
129
|
+
f"{float(row[N-1].tax_savings_percentage):.4f}", # "NULL" when NULL
|
|
130
|
+
row[N-1].sieved_content,
|
|
131
|
+
])
|
|
132
|
+
)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The NUL delimiter closes length-substitution field-boundary attacks. Fixed-precision
|
|
136
|
+
`:.4f` serialisation for `tax_savings_percentage` ensures that a Python `int` supplied at
|
|
137
|
+
append time and a SQLite `REAL` extracted at verification time both produce the identical
|
|
138
|
+
canonical token, preventing silent chain divergence.
|
|
139
|
+
|
|
140
|
+
Any out-of-band mutation of any stored value — textual payload, ingestion timestamp,
|
|
141
|
+
FinOps telemetry, or cryptographic fields — immediately breaks the chain and is detected
|
|
142
|
+
by `verify_ledger_integrity()`.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Thread safety
|
|
147
|
+
|
|
148
|
+
Each thread that accesses a shared `SovereignLedger` instance receives its own isolated
|
|
149
|
+
`sqlite3.Connection` via the internal `_get_conn()` method. `BEGIN IMMEDIATE` and a
|
|
150
|
+
5-second `busy_timeout` serialise writes at the SQLite reserved-lock level, preventing
|
|
151
|
+
sibling-fork `parent_hash` collisions without requiring a Python-layer mutex.
|
|
152
|
+
|
|
153
|
+
The closed-state flag is set atomically inside the connection-registry lock during
|
|
154
|
+
`close()`, eliminating the race window where a thread could slip past the guard and
|
|
155
|
+
register a dangling connection handle after teardown.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Integration pattern
|
|
160
|
+
|
|
161
|
+
`sovereign-ledger` slots into the end of the Sovereign pipeline:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
[Inbound Payload]
|
|
165
|
+
→ sovereign-sieve (Prose Tax reduction)
|
|
166
|
+
→ sovereign-core (Ed25519 sign → ForensicReceipt)
|
|
167
|
+
→ sovereign-ledger (append_receipt → immutable audit record)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from sovereign_core import SovereignGateway
|
|
172
|
+
from sovereign_ledger import SovereignLedger
|
|
173
|
+
|
|
174
|
+
gateway = SovereignGateway(signing_key=".keys/sovereign_identity.pem")
|
|
175
|
+
|
|
176
|
+
with SovereignLedger(db_path=".keys/sovereign_audit.db") as ledger:
|
|
177
|
+
response = await gateway.sieve_and_sign(raw_payload)
|
|
178
|
+
tip = ledger.append_receipt(response.receipt, response.content)
|
|
179
|
+
assert ledger.verify_ledger_integrity(expected_tip_hash=tip)
|
|
180
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sovereign-sdk-ledger"
|
|
7
|
+
version = "1.3.0"
|
|
8
|
+
description = "Immutable, local-first, hash-chained SQLite provenance engine for ForensicReceipt Write-Side Custody"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
classifiers = [
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Topic :: Security",
|
|
17
|
+
"Topic :: Database",
|
|
18
|
+
"Topic :: Software Development :: Libraries",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/kenwalger/sovereign-sdk"
|
|
23
|
+
Repository = "https://github.com/kenwalger/sovereign-sdk"
|
|
24
|
+
Changelog = "https://github.com/kenwalger/sovereign-sdk/blob/main/CHANGELOG.md"
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# packages/sovereign-ledger/src/sovereign_ledger/__init__.py
|
|
2
|
+
"""sovereign-ledger — Immutable, local-first, hash-chained SQLite provenance engine.
|
|
3
|
+
|
|
4
|
+
Provides an append-only audit ledger for ForensicReceipt transactions with
|
|
5
|
+
cryptographic hash-chain lineage verification and engine-level Write-Side
|
|
6
|
+
Custody enforcement. Zero external dependencies beyond the Python standard
|
|
7
|
+
library.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .engine import SovereignLedger, SovereignStorageError
|
|
11
|
+
|
|
12
|
+
__version__ = "1.3.0"
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"SovereignLedger",
|
|
16
|
+
"SovereignStorageError",
|
|
17
|
+
]
|