proof-aware-crypto-tooling-.../provider/src/pacta_provider/transparency_log.py

356 lines
16 KiB
Python
Raw Normal View History

2026-07-03 12:09:34 +00:00
from __future__ import annotations
import hashlib
import json
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
from pacta.dogfood import BACKEND_OPENSSL, BACKEND_VERIFIED, load_provenance, locate_verifier
2026-07-03 12:09:34 +00:00
from pacta.signing import canonical_json
from pacta.transparency import (
HASH_ALGORITHM,
RECEIPT_TYPE,
attestation_leaf,
consistency_proof,
inclusion_proof,
leaf_bytes_for_attestation,
leaf_hash,
make_signed_tree_head,
merkle_root,
proof_to_hex,
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
verify_inclusion,
2026-07-03 12:09:34 +00:00
)
from pacta.yamlio import dump_data, load_data
@dataclass(slots=True)
class LogEntry:
index: int
leaf: dict[str, Any]
leaf_hash: str
def leaf_bytes(self) -> bytes:
return canonical_json(self.leaf)
class TransparencyLog:
def __init__(self, log_dir: str | Path) -> None:
self.log_dir = Path(log_dir)
self.metadata_path = self.log_dir / "metadata.json"
self.entries_path = self.log_dir / "entries.jsonl"
self.sth_path = self.log_dir / "sth.yaml"
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
self.sth_history_path = self.log_dir / "sth-history.jsonl"
2026-07-03 12:09:34 +00:00
def init(self, provider: str, public_key_path: str | Path) -> dict[str, Any]:
if self.metadata_path.exists() or self.entries_path.exists():
raise ValueError(f"Transparency log already exists: {self.log_dir}")
self.log_dir.mkdir(parents=True, exist_ok=True)
public_key = Path(public_key_path).read_bytes()
log_id = hashlib.sha256(b"pacta-log-v1\0" + provider.encode("utf-8") + b"\0" + public_key).hexdigest()
metadata = {
"schema_version": 1,
"type": "pacta.transparency.log_metadata.v1",
"provider": provider,
"log_id": log_id,
"hash_algorithm": HASH_ALGORITHM,
"ed25519_public_key_fingerprint_sha256": hashlib.sha256(public_key).hexdigest(),
"created_at": _now(),
"standards": [
"RFC 9162 Merkle tree hash and inclusion/consistency proof algorithms",
"RFC 8032 Ed25519 signature verification via OpenSSL",
"FIPS 204 ML-DSA signature slot; must be required by policy only when a backend is configured",
],
}
self.metadata_path.write_text(json.dumps(metadata, indent=2, sort_keys=True) + "\n", encoding="utf-8")
self.entries_path.write_text("", encoding="utf-8")
return metadata
def metadata(self) -> dict[str, Any]:
if not self.metadata_path.exists():
raise ValueError(f"Transparency log is not initialized: {self.log_dir}")
raw = json.loads(self.metadata_path.read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise ValueError(f"Invalid transparency log metadata: {self.metadata_path}")
return raw
def entries(self) -> list[LogEntry]:
if not self.entries_path.exists():
return []
entries: list[LogEntry] = []
for line_number, line in enumerate(self.entries_path.read_text(encoding="utf-8").splitlines(), start=1):
if not line.strip():
continue
raw = json.loads(line)
if not isinstance(raw, dict):
raise ValueError(f"Invalid log entry at line {line_number}: {self.entries_path}")
leaf = raw.get("leaf")
if not isinstance(leaf, dict):
raise ValueError(f"Invalid leaf at line {line_number}: {self.entries_path}")
entries.append(LogEntry(index=int(raw["index"]), leaf=leaf, leaf_hash=str(raw["leaf_hash"])))
return entries
def latest_sth(
self,
private_key_path: str | Path,
public_key_path: str | Path,
timestamp: str | None = None,
) -> dict[str, Any]:
metadata = self.metadata()
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
entries = self.entries()
leaves = [entry.leaf_bytes() for entry in entries]
2026-07-03 12:09:34 +00:00
sth = make_signed_tree_head(
metadata["log_id"],
len(leaves),
merkle_root(leaves).hex(),
timestamp or _now(),
private_key_path,
public_key_path,
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
signing_provenance=self.signing_provenance(entries),
2026-07-03 12:09:34 +00:00
)
dump_data(sth, self.sth_path)
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
self._record_sth(sth)
2026-07-03 12:09:34 +00:00
return sth
def append_attestation(
self,
attestation_path: str | Path,
private_key_path: str | Path,
public_key_path: str | Path,
receipt_out: str | Path | None = None,
) -> dict[str, Any]:
metadata = self.metadata()
attestation = load_data(attestation_path)
if not isinstance(attestation, dict):
raise ValueError(f"Attestation must be a mapping: {attestation_path}")
entries = self.entries()
previous_size = len(entries)
previous_root = merkle_root([entry.leaf_bytes() for entry in entries]).hex()
leaf = attestation_leaf(attestation)
leaf_bytes = leaf_bytes_for_attestation(attestation)
computed_leaf_hash = leaf_hash(leaf_bytes).hex()
existing = next((entry for entry in entries if entry.leaf_hash == computed_leaf_hash), None)
if existing:
index = existing.index
appended = False
else:
index = len(entries)
record = {"index": index, "leaf_hash": computed_leaf_hash, "leaf": leaf}
with self.entries_path.open("a", encoding="utf-8") as handle:
handle.write(json.dumps(record, sort_keys=True, separators=(",", ":")) + "\n")
entries.append(LogEntry(index=index, leaf=leaf, leaf_hash=computed_leaf_hash))
appended = True
leaves = [entry.leaf_bytes() for entry in entries]
sth = make_signed_tree_head(
metadata["log_id"],
len(leaves),
merkle_root(leaves).hex(),
_now(),
private_key_path,
public_key_path,
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
signing_provenance=self.signing_provenance(entries),
2026-07-03 12:09:34 +00:00
)
dump_data(sth, self.sth_path)
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
self._record_sth(sth)
2026-07-03 12:09:34 +00:00
consistency = []
if appended and previous_size > 0:
consistency = proof_to_hex(consistency_proof(leaves, previous_size))
receipt = {
"schema_version": 1,
"type": RECEIPT_TYPE,
"log_id": metadata["log_id"],
"hash_algorithm": HASH_ALGORITHM,
"attestation_path": str(attestation_path),
"attestation_digest_sha256": hashlib.sha256(canonical_json(attestation)).hexdigest(),
"leaf_index": index,
"leaf_hash": computed_leaf_hash,
"tree_size": len(leaves),
"inclusion_proof": proof_to_hex(inclusion_proof(leaves, index)),
"consistency": {
"from_tree_size": previous_size,
"from_root_hash": previous_root,
"proof": consistency,
"status": "not_applicable" if previous_size == 0 or not appended else "included",
},
"sth": sth,
}
if receipt_out:
Path(receipt_out).parent.mkdir(parents=True, exist_ok=True)
dump_data(receipt, receipt_out)
return receipt
The provider eats its own dogfood: root signatures via the merkleized library The dogfood principle now runs in BOTH directions. Agents already verified signatures through the proven dalek path; now the provider SIGNS with it too, and proves to itself that the signing code is in its own log before every signature: - dogfood binary gains a `sign` mode (seed over stdin, never argv; ed25519_dalek::SigningKey from the same pinned merkleized workspace). Honesty ledger unchanged: the library's VERIFY path is certificate-covered; its signing path is declared trusted base - but it is the ATTESTED artifact, not an un-attested third implementation. - sign_payload_ed25519_detailed: signing dispatch mirroring the verify dispatch; the backend that actually signed is recorded in every attestation signature block and STH. - THE SELF-REFERENTIAL CHECK: before signing any tree head, the provider runs the SAME Merkle inclusion verification an agent runs - against the very tree it is about to sign - for the newest leaf attesting the signing library itself, and embeds the result in the signature block: signing_provenance: signing_backend: verified-dalek-serial signing_library_component: dalek-ed25519-verified signing_library_source_commit: aa0f6ab... self_inclusion: verified signing_library_leaf_index: 4 signing_library_certificates_proven: 16/16 A root signature that names the leaf vouching for the code that produced it. First-append chicken-and-egg is handled honestly (self_inclusion: library_not_in_log). - Evidence refreshed: all four receipts re-issued under dogfood-signed STHs; the full agent verify loop re-run green. 50/50 tests (new signing roundtrip test, skip-safe where unbuilt). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:21:17 +00:00
def signing_provenance(self, entries: list[LogEntry], signing_library_component: str = "dalek-ed25519-verified") -> dict[str, Any]:
"""THE PROVIDER EATS ITS OWN DOGFOOD: before signing a tree head,
verify that the attestation of the SIGNING LIBRARY ITSELF (the
merkleized dalek source whose build produced the signing binary) is
included in the very tree about to be signed - by running the same
Merkle inclusion verification an agent runs. The result is recorded
inside the signature block: a root signature that names the leaf
vouching for the code that produced it."""
binary = locate_verifier()
backend = BACKEND_VERIFIED if binary is not None else BACKEND_OPENSSL
provenance: dict[str, Any] = {
"signing_backend": backend,
"signing_library_component": signing_library_component,
}
if binary is not None:
build = load_provenance(binary)
if build.get("source_commit"):
provenance["signing_library_source_commit"] = build["source_commit"]
matches = [
entry
for entry in entries
if ((entry.leaf.get("attestation") or {}).get("subject") or {}).get("component") == signing_library_component
]
if not matches:
provenance["self_inclusion"] = "library_not_in_log"
return provenance
newest = matches[-1]
leaves = [entry.leaf_bytes() for entry in entries]
proof = inclusion_proof(leaves, newest.index)
verified = verify_inclusion(
newest.leaf_bytes(), newest.index, len(leaves), proof, merkle_root(leaves)
)
provenance["self_inclusion"] = "verified" if verified else "FAILED"
provenance["signing_library_leaf_index"] = newest.index
attested = (newest.leaf.get("attestation") or {}).get("certificates") or []
clean = sum(1 for c in attested if c.get("status") == "proven" and c.get("axiom_status") == "clean")
provenance["signing_library_certificates_proven"] = f"{clean}/{len(attested)}"
return provenance
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
def _record_sth(self, sth: dict[str, Any]) -> None:
with self.sth_history_path.open("a", encoding="utf-8") as handle:
handle.write(json.dumps(sth, sort_keys=True, separators=(",", ":")) + "\n")
def sth_history(self) -> list[dict[str, Any]]:
if not self.sth_history_path.exists():
return []
return [
json.loads(line)
for line in self.sth_history_path.read_text(encoding="utf-8").splitlines()
if line.strip()
]
def proof_for_leaf_hash(self, leaf_hash_hex: str) -> dict[str, Any] | None:
"""Read-only inclusion proof against the CURRENT tree for an existing
leaf - what the online service returns. Never signs anything."""
entries = self.entries()
match = next((entry for entry in entries if entry.leaf_hash == leaf_hash_hex), None)
if match is None:
return None
leaves = [entry.leaf_bytes() for entry in entries]
stored_sth = load_data(self.sth_path) if self.sth_path.exists() else None
return {
"schema_version": 1,
"type": RECEIPT_TYPE,
"log_id": self.metadata()["log_id"],
"hash_algorithm": HASH_ALGORITHM,
"leaf_index": match.index,
"leaf_hash": match.leaf_hash,
"tree_size": len(leaves),
"inclusion_proof": proof_to_hex(inclusion_proof(leaves, match.index)),
"sth": stored_sth,
}
def newest_entry_for_component(self, component: str) -> LogEntry | None:
matches = [
entry
for entry in self.entries()
if ((entry.leaf.get("attestation") or {}).get("subject") or {}).get("component") == component
]
return matches[-1] if matches else None
def publish(self, git_dir: str | Path, public_key_path: str | Path | None = None) -> dict[str, Any]:
"""Export the PUBLIC face of the log into a git-publishable directory:
metadata, one file per leaf (append-only in git history too), the
full STH history (the witness channel: everyone who clones sees the
same heads), the latest head, and per-component convenience
receipts. Private keys never appear here."""
out = Path(git_dir)
(out / "entries").mkdir(parents=True, exist_ok=True)
(out / "receipts").mkdir(parents=True, exist_ok=True)
metadata = self.metadata()
(out / "log-metadata.json").write_text(json.dumps(metadata, indent=2, sort_keys=True) + "\n", encoding="utf-8")
entries = self.entries()
for entry in entries:
path = out / "entries" / f"{entry.index:06d}.json"
if not path.exists():
path.write_text(json.dumps({"index": entry.index, "leaf_hash": entry.leaf_hash, "leaf": entry.leaf}, indent=2, sort_keys=True) + "\n", encoding="utf-8")
if self.sth_history_path.exists():
(out / "sth-history.jsonl").write_text(self.sth_history_path.read_text(encoding="utf-8"), encoding="utf-8")
if self.sth_path.exists():
latest = load_data(self.sth_path)
(out / "latest-sth.json").write_text(json.dumps(latest, indent=2, sort_keys=True) + "\n", encoding="utf-8")
components = {}
for entry in entries:
component = ((entry.leaf.get("attestation") or {}).get("subject") or {}).get("component")
if component:
components[component] = entry
for component, entry in components.items():
receipt = self.proof_for_leaf_hash(entry.leaf_hash)
(out / "receipts" / f"{component}.receipt.json").write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8")
(out / "entries" / f"{component}.attestation.json").write_text(
json.dumps(entry.leaf.get("attestation"), indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
publish assets: sync the fail-open time bomb; llms/course/test docs refreshed (doc audit 2026-07-19) REAL DEFECT found by the operator-ordered doc-freshness audit: published_assets.py still carried the PRE-HARDENING fail-open verify.py and the pre-Tier-2 README as the templates that log-publish drops into the mirror — the next publish would have silently overwritten the round-13-hardened fail-closed verifier and the corrected README with the old versions. Fixed: - published_assets.py regenerated from the canonical mirror files (byte-identity verified by round-trip exec), now also carrying verify_selftest.py; SYNC RULE documented in the module docstring. - transparency_log.publish() now writes verify_selftest.py too. - NEW tests/test_published_assets.py pins the security-critical markers (fail-closed FATAL, RECEIPT_TYPE, verify_receipt, --all receipt coverage, required fingerprint) so template drift fails CI instead of shipping. - test_web_and_witness updated to the hardened verifier's markers — the published test log now passes FULL signature mode end to end ('RESULT: OK [full]'), a stronger assertion than the old string. Doc refresh in the same pass: - llms.txt: thirteen leaves + entry-13 self-attestation + fail-closed verifier; paper line -> new title, 23 pages, v0.2/v0.1 archives. - Course (generator + generated 06b notebook): 'the git hash IS the content hash' -> 'the commit pins the exact source tree'; 'irrevocably part of the log every other agent sees' -> 'committed to the log's signed view, which any agent can compare' (the two Tier-2 scope corrections had never reached the teaching material). - test_paper_verifiers.py docstring rescoped: its 164k counts are the archived v0.2 report's citation; the current paper cites the corpus harness and makes no extensional-equality claim. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:10:55 +00:00
from .published_assets import README_MD, VERIFY_PY, VERIFY_SELFTEST_PY
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
(out / "verify.py").write_text(VERIFY_PY, encoding="utf-8")
publish assets: sync the fail-open time bomb; llms/course/test docs refreshed (doc audit 2026-07-19) REAL DEFECT found by the operator-ordered doc-freshness audit: published_assets.py still carried the PRE-HARDENING fail-open verify.py and the pre-Tier-2 README as the templates that log-publish drops into the mirror — the next publish would have silently overwritten the round-13-hardened fail-closed verifier and the corrected README with the old versions. Fixed: - published_assets.py regenerated from the canonical mirror files (byte-identity verified by round-trip exec), now also carrying verify_selftest.py; SYNC RULE documented in the module docstring. - transparency_log.publish() now writes verify_selftest.py too. - NEW tests/test_published_assets.py pins the security-critical markers (fail-closed FATAL, RECEIPT_TYPE, verify_receipt, --all receipt coverage, required fingerprint) so template drift fails CI instead of shipping. - test_web_and_witness updated to the hardened verifier's markers — the published test log now passes FULL signature mode end to end ('RESULT: OK [full]'), a stronger assertion than the old string. Doc refresh in the same pass: - llms.txt: thirteen leaves + entry-13 self-attestation + fail-closed verifier; paper line -> new title, 23 pages, v0.2/v0.1 archives. - Course (generator + generated 06b notebook): 'the git hash IS the content hash' -> 'the commit pins the exact source tree'; 'irrevocably part of the log every other agent sees' -> 'committed to the log's signed view, which any agent can compare' (the two Tier-2 scope corrections had never reached the teaching material). - test_paper_verifiers.py docstring rescoped: its 164k counts are the archived v0.2 report's citation; the current paper cites the corpus harness and makes no extensional-equality claim. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:10:55 +00:00
(out / "verify_selftest.py").write_text(VERIFY_SELFTEST_PY, encoding="utf-8")
The log goes public: git-published mirror, online service, witnesses Three synchronized faces of one log - transport orthogonal to trust: - PUBLISHED GIT MIRROR: log-publish exports the public face (one file per leaf so git history mirrors log history; the FULL STH history as the witness channel; per-component attestations + receipts; the provider public key; a standalone stdlib-only verify.py and customer README). Live at github.com/saymrwulf/lean-transparency-log (genesis: 8 leaves incl. the honest failed-run entries, dogfood-signed head). - ONLINE SERVICE (pacta_provider serve): read-only, zero-dependency HTTP with CT-style endpoints under a base path for zkdefi.org/lean-transparency-log - /v1/sth, /v1/sth-history, /v1/sth-consistency?first=N, /v1/proof, /v1/attestation, /v1/entries, /v1/metadata, /healthz - plus self-contained customer documentation at /docs (current state, attested components, API, the verify- without-trusting-this-site path, and the means/does-NOT-mean boundary). The process never loads private keys: heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect both) but never forge. STH history now recorded append-only by the provider (with a backfill head signed for the existing log). - AGENT ONLINE CLIENT: pacta log-fetch (download evidence; explicitly UNVERIFIED until receipt-verify runs - transport is not trust) and pacta sth-refresh (fetch head, verify signature, advance the pin via an online consistency proof from the pinned size; fail closed). - WITNESSES: pacta witness-audit over a clone of the published mirror recomputes every prefix root from the public leaves and checks every historical head + signature - no consistency proofs needed when the leaves are public. Tampering one published entry trips both the leaf-hash check and the prefix-root check (tested). verify.py gives customers the same audit with zero installation. - DEPLOY.md: the complete server-session checklist for zkdefi.org - reconstruct the servable log FROM the published mirror (the server stays in witness trust-position), hardened systemd unit, nginx/Caddy path routing, Forgejo mirror setup, the provider->world update cycle, and remote smoke tests. Validated end-to-end on the REAL log: all 10 endpoints, online-fetched proof re-verified locally through the dogfood verifier with pinning, online pin refresh, publish + witness audit green, tamper caught, standalone verify.py green in the published clone. 54/54 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:05:20 +00:00
(out / "README.md").write_text(README_MD, encoding="utf-8")
if public_key_path is not None:
(out / "provider.ed25519.pub").write_bytes(Path(public_key_path).read_bytes())
return {"entries": len(entries), "components": sorted(components), "out": str(out)}
Log accountability: STH pinning, consistency enforcement, freshness, monitor A transparency log without split-view defense is just a signature with extra steps: the provider could serve one tree to the agent and another to the world, or roll the log back, and standalone receipt verification would never notice. The primitives (RFC 9162 consistency proofs) were already implemented and correct; this closes the loop on the AGENT side. - src/pacta/sthstore.py: a local STH pin store. Unknown log -> pin (trust-on-first-use, recorded as such). Same tree size -> the root must match the pin byte-for-byte; a mismatch is named EQUIVOCATION and is a hard rejection. Larger tree -> a consistency proof FROM THE PINNED SIZE is required and verified before the pin advances (receipts already embed a from-previous anchor; the anchor's root is itself checked against the pin so a lying anchor cannot bridge a split view). Smaller tree -> LOG ROLLBACK, hard rejection. - Freshness policy: --max-sth-age-seconds rejects stale (or future-dated) tree heads - an old-but-valid STH can hide later entries. - Wired into receipt-verify, claims, and agent (--sth-store, --consistency-proof, --max-sth-age-seconds); evidence records the pin action; any accountability failure fails the receipt closed. - Provider: log-consistency --from-size N (serve proofs for pinning agents whose pin is older than the receipt's embedded anchor) and log-audit (monitor self-check: recompute the tree, verify the stored STH and per-entry leaf hashes). Live drill in this commit's validation: pin-on-first-use -> matched -> grown-with-proof advance -> a real forged same-size split view REJECTED with the equivocation diagnostic -> freshness rejection -> clean self-audit. tests/test_sthstore.py covers pin/match/equivocation, growth-without-proof, lying consistency anchors, rollback, freshness. 45/45 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 08:08:34 +00:00
def consistency_from(self, old_tree_size: int) -> dict[str, Any]:
"""Consistency proof from an arbitrary earlier tree size - what a
pinning agent requests when its pin is older than the receipt's
embedded from_tree_size."""
entries = self.entries()
leaves = [entry.leaf_bytes() for entry in entries]
if old_tree_size < 0 or old_tree_size > len(leaves):
raise ValueError(f"old_tree_size {old_tree_size} outside tree size {len(leaves)}")
return {
"schema_version": 1,
"type": "pacta.transparency.consistency_proof.v1",
"log_id": self.metadata()["log_id"],
"from_tree_size": old_tree_size,
"from_root_hash": merkle_root(leaves[:old_tree_size]).hex(),
"to_tree_size": len(leaves),
"to_root_hash": merkle_root(leaves).hex(),
"proof": proof_to_hex(consistency_proof(leaves, old_tree_size)),
}
def audit(self) -> dict[str, Any]:
"""Monitor-side self-check: recompute every prefix root, confirm the
stored STH matches the full tree, and confirm every prefix is
consistent with the final tree (append-only structure)."""
entries = self.entries()
leaves = [entry.leaf_bytes() for entry in entries]
problems: list[str] = []
for position, entry in enumerate(entries):
if entry.index != position:
problems.append(f"Entry at position {position} carries index {entry.index}.")
if leaf_hash(entry.leaf_bytes()).hex() != entry.leaf_hash:
problems.append(f"Entry {position} leaf_hash does not match its leaf bytes.")
computed_root = merkle_root(leaves).hex()
stored_sth = load_data(self.sth_path) if self.sth_path.exists() else None
if stored_sth:
if stored_sth.get("tree_size") != len(leaves):
problems.append("Stored STH tree_size does not match the entry count.")
if stored_sth.get("root_hash") != computed_root:
problems.append("Stored STH root hash does not match the recomputed tree root.")
return {
"tree_size": len(leaves),
"computed_root": computed_root,
"stored_sth_root": (stored_sth or {}).get("root_hash"),
"problems": problems,
"ok": not problems,
}
2026-07-03 12:09:34 +00:00
def _now() -> str:
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")