witness-log (Python)
Python bindings for witness-log-core and witness-log-network, built
with PyO3/maturin. Same wire format as the Rust crates and the same
guarantees: see the root README.md and THREAT_MODEL.md before using
this for anything real. Ships type stubs (py.typed).
Install
pip install witness-log
abi3 wheels for Linux x86_64/aarch64 (glibc and musl), macOS x86_64/arm64
and Windows x86_64, Python ≥ 3.9; the same files with SHA256SUMS are on
the GitHub release.
To build from source: pip install maturin && maturin build --release
in this directory.
Quickstart: an agent loop
import witness_log
log = witness_log.open("agent.jsonl") # create, or resume if it exists
@witness_log.step(log) # one line per tool
def transfer_funds(amount_usd: int) -> dict:
return {"status": "ok", "tx_id": "tx_7ac31"}
transfer_funds(250) # two leaves: intent, then result
log.sync() # fsync when you need durability
pii = log.append_memory(b"contact: alice@example.com")
log.forget(pii) # right-to-be-forgotten: the salt is erased from agent.jsonl.salts
# and a marker leaf appended; every earlier proof is unchanged.
dossier = log.to_dossier_json() # the bundle anyone can verify offline
report = witness_log.verify_dossier_json(dossier, 0.66, log.identity_pubkey_hex())
log.close()
witness_log.open(path, identity_seed=None) creates path with a new
identity (or identity_seed, 32 bytes you keep) and resumes it on every
later run. The journal is two files, agent.jsonl and agent.jsonl.salts,
both 0600; the first line of the journal holds the identity private
key, so protect and back up both like key material. A process killed while
holding the journal leaves agent.jsonl.lock; on Linux resume clears it
when the recorded PID is gone, elsewhere call
JournaledLog.force_unlock(path) once you are sure nothing else has it open.
Any dossier produced here verifies with the Rust CLI unmodified:
witness-log verify dossier.json --identity <hex> --directory witnesses.json
That cross-language round trip is what the wire format (spec/SPEC.md)
and conformance corpus (/corpus/) exist to guarantee.
Getting WITNESSED
A dossier with no independent cosignatures verifies as unanchored (or
consistent_unwitnessed with a directory). To reach witnessed, at least
two witnesses with distinct operator_org values in the verifier's
directory must cosign the head:
w = witness_log.Witnesser(log, "trusted.json", "agent.jsonl") # background thread
w.request() # never blocks, never raises
if w.flush(timeout=30): # bounded wait for the current head
report = witness_log.verify_dossier_json(w.dossier(), 0.66, log.identity_pubkey_hex(),
open("trusted.json").read())
print(w.status()) # witnessed_size, cosignatures, last_error (structured)
Witnesser follows 409 resyncs, honours Retry-After, backs off when
witnesses are down, keeps its state in <journal>.witnesses.json (the
CLI's file and format) and refuses to submit a journal that contradicts a
head witnesses already cosigned. await w.aflush() in asyncio code;
witness_log.submit_round(...) for one synchronous round. The protocol
primitives underneath are add_checkpoint_body(old_size) and
dossier_from_responses(...) (and their _at(size, ...) forms).
Extras
| extra | gives you |
|---|---|
witness-log[mcp] |
the MCP server: witness-log-mcp (stdio), ten tools including submit_to_witnesses |
witness-log[langchain] |
witness_log.integrations.langchain.WitnessLogCallbackHandler |
witness-log[openai-agents] |
witness_log.integrations.openai_agents.WitnessLogHooks |
witness-log[crewai] |
witness_log.integrations.crewai.witness_crewai |
Running a witness
WitnessService.new(key_name, seed, state_path, open_enrollment=True) is a
witness you can mount in any web framework: hand it the body of each
POST /add-checkpoint and send back what it returns. Create its state once
with WitnessService.create_state(path); the state file is bound to the
witness key and persisted before any cosignature leaves the process.
examples/live-network/py_witness.py
is a complete 60-line server.
API surface
Everything is typed in python/witness_log/_core.pyi.
witness_log.open(path, identity_seed=None) |
JournaledLog: create or resume. |
witness_log.step(log, name=None, *, record_result=True, sync=False) |
Decorator: intent leaf before the call, result (or error) leaf after. Sync and async. |
witness_log.canonical_json(value) |
The byte form step hashes. |
JournaledLog.create(path, seed) / .create_ephemeral(path) / .resume(path) |
Explicit constructors; resume returns (log, dropped_trailing_lines). |
.append_intent/.append_result/.append_memory(bytes) |
New leaf index. |
.append_handoff_sent/.append_handoff_received(state, counterparty_hex) |
SPEC §3.1 cross-log binding. |
.forget(i) / .can_forget(i) |
Redaction; works for leaves from earlier sessions. |
.checkpoint() / .to_dossier_json() / .leaves_json() |
JSON, SPEC §6 / §9 / §2. |
.inclusion_proof(i) → (tree_size, root_hex, path) |
Check offline with verify_inclusion(...). |
.add_checkpoint_body(old_size) / .dossier_from_responses(...) |
Witness protocol client; _at(size, ...) forms pin an earlier head; .root_hex_at(size). |
Witnesser(log, directory, path) / submit_round(log, directory, state_path) |
Background / one-shot witnessing (see above). |
.sync() / .close() / context manager |
Durability; releasing the lock. |
JournaledLog.force_unlock(path) |
After a crash, when resume cannot tell the holder is gone. |
WitnessLog |
The in-memory core (snapshots, no salt persistence). |
WitnessService |
A tlog-witness witness. |
verify_dossier_json(dossier, threshold, identity=None, directory_json=None) |
The CLI's verifier; report JSON with verdict, identity_pinned, internally_consistent, quorum. |
verify_inclusion(leaf_hash_hex, index, tree_size, path, root_hex) |
RFC 6962 inclusion check. |
select_diverse_witnesses(directory_json, subject_pubkey, want) / select_witnesses(...) |
Pick operator-diverse witnesses from a directory (object or bare list). |
witness_entry_independent(...) / witness_entry_project_operated(...) |
Build directory entries. |
Errors: WitnessLogError (base), SignatureError, ContinuityError,
MalformedError; I/O failures raise OSError; bad arguments raise
ValueError/TypeError. Payloads are bytes.
This crate is intentionally thin: it does not reimplement any
serialization logic; every JSON shape here is the Rust crates' own serde
output, so it stays in lockstep with spec/SPEC.md by construction.
Metadata
Release files for witness-log 0.3.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| witness_log-0.3.6.tar.gz | 266.6 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| witness_log-0.3.6-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| witness_log-0.3.6-cp39-abi3-musllinux_1_2_x86_64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ x86-64 | Details |
| witness_log-0.3.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| witness_log-0.3.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| witness_log-0.3.6-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| witness_log-0.3.6-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 4.7 MB
Release files / witness_log-0.3.6.tar.gz
| Download URL | witness_log-0.3.6.tar.gz |
|---|---|
| Size | 266.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
18447188964d801ee33cd5adf6d023dcf3ebef570ff9af6bdda6896730ec0114
|
|
BLAKE2b-256 checksum How to use checksums |
d9fc842c543b819d485f7a66dae5b29d15a2f38be83094e62f4e16c55dbacb1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-win_amd64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 669.3 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
736283860a264f3b10129d1a5a1a475202b772279eecd81db2de1f2b8da414ac
|
|
BLAKE2b-256 checksum How to use checksums |
92f7f1eb1c99c94e1b32e99c1e741541ec9c6ea8c8c64e62cc263e8d320c5401
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 946.1 kB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4d5c6056a87b9f059c856acc0ec6ea2c7ce2c344e99c5304d24949d61a56e10c
|
|
BLAKE2b-256 checksum How to use checksums |
3a08efd6a23294de02c61122e5e82b41be5c62007229fcc9a24cf16c5057cd4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 733.0 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
96be569a3acaeb8a40a0e677379f628ca267ac730e4d833979883f1097681d51
|
|
BLAKE2b-256 checksum How to use checksums |
80690808deaa8d123153cb9839da3fcb7c4e6d6f707183109291480129cc7307
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 680.6 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ff3c28fdd0cf79eabc1f4a3544ca0a6d367187399803b33365e6c0c511b2f9ca
|
|
BLAKE2b-256 checksum How to use checksums |
2b6a560aa8c3ff57cbcc1ea9f6115db6ade834579c500bdc7afcda37c93c9b1a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 654.9 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
75fe7bc4c8ae08e0d73d7a41fc741dcf67f874224e9e2b2254fbfbe3543a5853
|
|
BLAKE2b-256 checksum How to use checksums |
09561a1800605703a5f0dea9b5c982f99c7c171b09c1e8b5a2cfdece54e14a95
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / witness_log-0.3.6-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | witness_log-0.3.6-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 703.3 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
7df44f8ccd9363c2731452c392de21dfabf96321dcbdacf13381c6bc179f79e4
|
|
BLAKE2b-256 checksum How to use checksums |
c5b0950c2c1e86e13de7e1353405f194584d781782002a7b202ce8ab3d4c2408
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log