Commit graph

5 commits

Author SHA1 Message Date
2587cc018b 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 13:10:55 +02:00
fbe40c3dfe 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 16:05:20 +02:00
b8ffbafa7f 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 15:21:17 +02:00
7c717d03fc 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 10:08:34 +02:00
0461d2f997 add transparency log trust provider 2026-07-03 14:09:34 +02:00