Metadata-Version: 2.4
Name: truthlayer-ledger-verify
Version: 0.1.0
Summary: Offline verifier for the TruthLayer tamper-evident agent-activity ledger — a faithful Python port of the TypeScript truthlayer-ledger-verify (seals, events, inclusion, OTS→Bitcoin anchors, completeness, residency, disclosure, causality, bilateral/bond, DNSSEC-STH, and PDF documents).
Author: Karl F. Ambrosius
License: MIT License
        
        Copyright (c) 2026 provenance-verify contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/kambrosgroup/TruthLayer
Project-URL: Repository, https://github.com/kambrosgroup/TruthLayer
Keywords: truthlayer,provenance,ledger,verification,offline-verifier,merkle-proof,rfc6962,rfc8785,ed25519,ml-dsa,slh-dsa,opentimestamps,post-quantum,audit
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Legal Industry
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=42
Requires-Dist: dilithium-py>=1.1
Requires-Dist: slh-dsa>=0.2.3
Requires-Dist: blake3>=0.4
Requires-Dist: pypdf>=4
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# truthlayer-ledger-verify (Python)

**An offline verifier for the TruthLayer tamper-evident agent-activity ledger** — a faithful Python port of the TypeScript [`truthlayer-ledger-verify`](https://www.npmjs.com/package/truthlayer-ledger-verify) (npm). It checks the ledger's cryptographic claims from **public artifacts alone**; no TruthLayer endpoint is ever contacted (the sole networked path is `--dns`, a tolerant DoH corroboration that only ever *strengthens* or warns, never a trust root).

MIT licensed. Python ≥ 3.10. Pure-Python / pip-wheel dependencies only — no native builds, no OQS, no BLS.

## Install

> Not yet published to PyPI. Until the first release, install from source (Python ≥ 3.10):
>
> ```bash
> pip install ./tools/ledger-verify-py
> ```

Once published:

```bash
pip install truthlayer-ledger-verify
```

## CLI (`ledger-verify`)

```bash
# Daily seal(s): event chain → hourly sub-seals → daily root → OTS→Bitcoin anchor
ledger-verify --tenant-id <t> --agent-id <a> --date <YYYY-MM-DD> --dir <bundle>
ledger-verify --tenant-id <t> --agent-id <a> --from <d1> --to <d2> --dir <bundle>

# Single exported event (+ optional inclusion proof)
ledger-verify --tenant-id <t> --event <event.json> [--payload <p.json>] [--target-event <e.json>] \
              [--agent-id <a> --inclusion <proof.json>] --dir <bundle>

# Document (self-contained PDF with an embedded evidence bundle)
ledger-verify --tenant-id <t> --doc <doc.pdf> --doc-event <e.json> --doc-payload <p.json>

# Coverage / completeness attestation
ledger-verify --tenant-id <t> --completeness <att.json> [--predicate-proof <proof.json>] --dir <bundle>

# Migration lineage · residency · bilateral evidence · causality · selective disclosure
ledger-verify --tenant-id <t> --agent-id <a> --lineage --dir <bundle>
ledger-verify --residency <proof.json> --dir <bundle>
ledger-verify --bilateral <eventA.json> [--counterpart <eventB.json>] --dir <bundle>
ledger-verify --tenant-id <t> --causality <subgraph.json> [--payloads <p.json>] --dir <bundle>
ledger-verify --tenant-id <t> --disclosure <export.json> --dir <bundle>

# DNSSEC-STH corroboration (networked, tolerant — mismatch is the only failure)
ledger-verify --dns <zone> --sth <sth.json> --date <YYYY-MM-DD>
```

Exit codes: `0` ok · `1` a check failed (fail-closed) · `2` usage error. `--dir <path>` reads a local bundle; `--base-url <url>` reads a static mirror.

## Library

```python
from truthlayer_ledger_verify import DirSource, verify_day
r = verify_day(DirSource("bundle"), {"tenantId": "tnt_…", "agentId": "agt_…", "date": "2026-07-25"})
print(r["ok"], r["checks"])
```

## What it verifies

- **RFC 8785 (JCS)** canonicalization and **RFC 6962 / RFC 9162** Merkle inclusion & consistency, byte-identical to the signer.
- **Hybrid-AND signatures** — Ed25519 (RFC 8032) + ML-DSA-65 (FIPS 204) + SLH-DSA-SHA2-128f (FIPS 205); the two-level daily/hourly seal structure, the per-event inclusion path, and the two-level root→time-bounded-subkey trust chain + SLH-DSA root certifications.
- **OpenTimestamps → Bitcoin** anchor (parsed and executed offline).
- **Bonded attestation, selective field-tree disclosure, causality subgraphs, migration lineage, data-residency proofs, coverage/completeness with a predicate AST, RFC 3161 TSA / Roughtime / drand time corroboration, and DNSSEC-STH corroboration.**
- Fail-closed on unknown formats/suites and missing required artifacts.

The crypto core is the same byte-parity core proven in `provenance-verify`, extended with the `@truthlayer/shared` primitives this verifier needs — all pure-Python (`cryptography`, `dilithium-py`, `slh-dsa`, `blake3`, `pypdf`).

## Faithfulness & validation

- `tests/test_conformance.py` — the shared `canon-vectors.json` corpus (JCS + v1/v2 Merkle) matches byte-for-byte.
- `tests/test_core_modes.py` — the daily-seal chain over a real committed bundle; the Python CLI emits a **byte-identical checks map to the TypeScript `ledger-verify` CLI**, and tampered/missing inputs fail closed.
- `tests/test_predicate.py` — the predicate AST (strict equality with the bool/int guard, mixed-type ordering fail-closed, `matches` search semantics, `assert_safe_regex` rejection); the `predicate_agg_root` leaf order reproduces the TS `localeCompare` collation exactly.

The exotic modes (documents, completeness, residency, disclosure, causality, bilateral) are faithful 1:1 ports whose crypto reduces to the conformance-proven primitives above; the reference TS package ships no golden fixtures for them, so they are validated by structure + primitive parity rather than committed golden vectors.

```bash
python3.12 -m venv .venv && .venv/bin/pip install -e ".[test]" && .venv/bin/pytest
```
