All six originated from the author's own adversarial read-through:
1. SS9: retrievability decay — leaves whose pinned commits are no longer
distributed (0-7 post-rewrite) decay to historical record.
2. SS4.3: why-a-tree — per-item signatures cannot evidence deletion,
expose forks, or provide pinnable state; dishonesty-evidence, not
scale, is the motivation.
3. SS1: curve/signature crate parenthetical (one implementation).
4. SS8: ~1,800s/fork corroborated by inter-leaf issued_at spacing
(within-run gaps 29m35s-30m40s).
5. SS5.1: git commit ids are hardened SHA-1 — said before a referee
says it.
6. App A box fidelity: logical-vs-canonical order declared; ellipsis
markers inside cert objects and at attestation level (covers
diagnostics + inner schema_version); '(14 more)' -> '(14
certificates elided)'.
Visual inspection: all changed pages (1,5,6,13,15,16,17) plus spill
pages 18-19 read with own eyes; p.19 is a light final page (App D
table), accepted over spacing tricks. 106 tests green, accumulator
untouched. Page-count refs updated (webdocs, llms.txt).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review A (second Fable instance, delivered via USB, findings re-verified
by me against the tex before adoption; its frontier lemma re-derived from
scratch before applying):
- THE REAL FIX: Lemma 2's hash-fold definition did not cover its own two
uses (Root recomputes only along the leaf's root path; ConsRec bottoms
out at the [0,n0) decomposition and consumes the pinned root, which the
old Steps 1-2 never pinned - incl. the degenerate case where the first
component IS the pinned root alone). Now: folds shaped by a connected
sub-tree S containing the root, children outside S consumed as opaque
inputs, conclusion pins emitted values AND all consumed inputs; Thm 2
names its S; Thm 3 pins the consumed anchor and handles the degenerate
case; Lemma 1's role stated honestly.
- dangling R4/R5 taxonomy labels removed; G3/Prop 2 statements now match
their own veto-proof (deny-only, everywhere); Table 1 caption counts
boundary+standard-three; r1 defined as raw signature bytes (T1's whole
point); Contribution 4 'embedded in every signature' -> 'published
alongside'; Figure 1 redrawn in the exact RFC 9162 shape for n=12;
Solana error-type nit; App D namespace elision noted.
Review B (GPT-5.6, positions defended 2026-07-10, concessions adopted):
- abstract + G2 narrowed to what Prop 1 proves (same-size evidence +
monotonicity), unequal-size split views routed through the public leaf
mirror; residual-trust sentence stated at honest width (checkout, deps,
binding, parsing in the trusted observation pipeline); freshness
declared an availability policy (freeze attacks not prevented);
self-reference verb 'ensures' -> 'enforces and records' + signature
reveals nothing about the producing program; novelty softened to
'we are unaware of'; 25-line/150-line accounting in one breath;
missing-oracle-axiom = refuse-to-classify drift (keeping the oracle
argument); mechanization tone softened; head-encoding reality
documented (versioned canonical JSON w/ log id - system was ahead of
the paper); NEW claim-matrix table (Table 2) decomposing every consumer
conclusion into mechanism + residual assumption, incl. two deliberate
not-established rows.
Open questions from Review A resolved: black_box 27 lines are per-lemma
trusted-base bookkeeping (no published cone contains black_box -
verified); T4 x=0 edge case now stated precisely (roots coincide, set
sign bit rejected per RFC 8032, covered by the iff over extracted code;
Lean sqrt_core handles x=0 explicitly); Cheval pages (DBLP-verified)
restored alongside Review A's DOI.
18 pages, 106 tests green, accumulator untouched (12 leaves).
webdocs/llms.txt page counts updated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two Fable-5 inventory agents cross-checked every empirical claim in the
paper against code/deployed log, and every external pointer against the
live internet. Fixes on both sides:
CODE (system brought up to the paper's claims):
- SECURITY: pin-store mutation (incl. permanent poisoning) was reachable
via receipts whose head signature FAILED verification in two of three
consumer paths (attestation.py, cli.py) - an unauthenticated forged
head at the pinned size could poison a consumer's pin forever and
pollute the equivocation-evidence pair with an unverifiable head,
contradicting SS5.4's 'validly signed' precondition and Prop 1.
Both paths now gate the store on a verified Ed25519 head signature
(logclient.py already did). Regression test added.
- Prop 2 made literally true: _normalize_certificate now derives the
cleanliness verdict purely from (observed cone, local allowed set) in
EVERY branch; the operator's axiom_status label is never copied (was
passed through for non-proven certs), missing cone => unverifiable
always. Labels can deny, never grant. Test added.
- webdocs: '/v1/sth-history: every head ever signed' -> 'the published
head history'.
PAPER (claims brought down to reality):
- 'every head ever signed' -> the signed head history since publication
began (heads for sizes 1-7 predate the mirror and were not retained).
- Run-3 bullet: 'independently checkable by diffing the two commit
trees' was no longer reproducible (pre-rewrite objects discarded);
now states the log-internal corroboration (identical cert lists and
cones across leaves 4-7 vs 8-11) and that tree diffs are not public.
- Appendix A leaf block now actually verbatim: scheme
openssl-ed25519, verified_backend serial/u64, real Lean version
(4.30.0-rc2) instead of 4.x.y placeholder, leaf's actual axiom order
(finalize/new/update), machine_protection note quoted, elisions
marked; preamble wording matches.
- Appendix C upstream boundary reordered to check.sh's verbatim order.
- '27 lines - all annotation' -> honest description (axiom-list entries
+ operation reordering from one fork's black_box barrier).
- Prop 2 proof + App A: status label consulted only negatively.
- SS7: provenance fields noted as outside the signed payload; consumer
chain relies on none of them.
- Bibliography: all 20 entries verified against DBLP/RFC-editor - zero
errors; added missing page numbers to 6 entries; thebibliography
width 19->20. All URLs verified public; no PlanetMacro leakage.
17 pages, 106 tests green, accumulator untouched (tree_size 12).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Not size for its own sake; each addition is a definition, proof, figure,
or measurement the genre expects and the rejection implied:
- §2: the signature apex given real depth — the four tiers stated as an
explicit lifting ladder T1-T4 (byte apex -> canonical half-lift ->
injectivity/point-eq via non-square d -> constructive full lift), each
naming the one new mathematical fact; the corpus's actual achievement,
previously an appendix bullet list
- §4: scheme-syntax Definition (KeyGen/Append/ProveIncl/VerifyIncl/
ProveCons/VerifyCons/Verdict) in DGHS style, so the goals name real
algorithms; new subsection making the observation-not-verdict /
requirements-card idea explicit (the system's distinguishing claim)
- §5.3: the consistency verifier DEFINED (recursive ConsRec form),
closing the gap where Theorem 3 previously reasoned about an
undefined verifier — differential-tested == deployed RFC verifier on
5508 cases (honest + 4 mutation classes, n<=256)
- §6: Theorem 3 now a FULL proof (was a sketch), factored through a
shared Lemma 2 (Root binding) that both soundness theorems use
- §8: Figure 1 (the twelve-leaf tree w/ grey failure leaves + 3-run
braces) reinstated and improved; Table 1 (per-fork files/boundary/
diff/hash-shape) replacing a prose paragraph
- App D slimmed to the verbatim Lean theorem-name mapping (no longer
duplicates §2)
Both recursive verifiers regression-tested against deployed code. 102
tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removal (user decision): paper/ltl-v0.0.{tex,pdf} deleted; /paper/v0.0
route removed; test now asserts 404 for it; /paper/v0.1 stays for
citability and is linked from the docs card.
Audit findings from re-reviewing the last session's work, all fixed:
- Appendix A claimed 'all other fields are verbatim' over elided
placeholder values - reworded to state exactly what is elided vs
verbatim (a paper about exactness cannot say verbatim over an ellipsis)
- LTL docs paper card still described the 4-page v1 (old title, old
scope) - now the revised title, 14 pages, proofs summary, v0.1 link
- llms.txt paper line updated to the revised title
- paper/eprint-submission.md rewritten as the RESUBMISSION kit: new
title/abstract, message-to-editors change note, form-not-email
guidance, author-only checklist
102 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paper:
- v2 (12->14pp: appendices) promoted to paper/ltl.tex; v1 kept as
ltl-v0.1.tex, pseudonymous variant as ltl-v0.0.tex (identity-clean)
- filled from verified artifacts: App C (3 verbatim per-fork boundaries:
dalek 11 / hash3 8 / anza 7), App D (real 4-tier ladder + parser
hypotheses; the other agent's 'Tier 3/4' guess corrected), App A (real
leaf 8 structure); §8 now twelve leaves / three runs incl. the
history-rewrite absorption (a live G2 demonstration); §7 self-check
index 4->8; Limitations count fixed; two overfull math displays fixed
- title/author/ORCID unchanged from the revision
Hosting: web.py serves /paper (current), /paper/v0.1 (prior named),
/paper/v0.0 (pseudonymous) - older versions unlisted in the endpoint
index; test added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The lecture-11 framing where customers actually land: the allowed-axioms
list as a card the customer owns and can rewrite; verdicts re-derived
against THEIR copy; stricter card => itemized gap => relax / walk away /
grow the supply. Links to lecture 11 for the executable walk-through.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Generic mechanism: bare-name PDFs placed in the log directory's site/
folder are served by name, checked LAST in the route chain (can never
shadow an API route), traversal-safe, noindex, and deliberately absent
from the endpoint index and the docs page - the operator decides who
receives a link. Tested: serve, unlisted-in-404, traversal rejected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The provider public key is the one thing a consumer takes on trust;
hiding it behind /log-public-key inverted the page's priorities. New
'The trust anchor - pin this key' section at the top of the docs page
shows the PEM in full with its SHA-256 fingerprint, the mirror-compare
instruction, and the raw endpoint for scripts. Honest 'missing' card if
a deployment lacks the key. Test asserts the page renders the key.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Socratic audit findings, all verified against artifacts:
- 'zero lines between structurally identical forks' was FALSE: risc0 vs
betrusted differ by 27 lines (all annotation, documenting the risc0
fork's black_box trusted-base entry). Corrected to the true number.
- '~64 Lean files per fork' over-rounded anza's 58. Now '58-64'.
- completeness parenthetical now states both hypotheses (a=-1 square, d
non-square), not just d.
- 'key published in two independent locations' was ASPIRATIONAL: the
site served only a fingerprint. New /log-public-key endpoint serves
the key bytes; docs-page artifact-1 row links both copies; test added.
Verified exactly and kept: 215-line parser diff (FromBytesSpec), 121-line
signature-glue diff (SigApexSpec), byte-identical x4 math files incl. the
carry-telescope file, 11-axiom upstream boundary, 16 certs/leaf, 153-line
mirror verifier, leaf fields (toolchain + machine_protection), all 17 refs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Title: 'LTL: Lean Transparency Log'; subtitle now 'Distributing
Machine-Checked Proof Evidence through a Recursively Self-Certifying
Merkle Log' (the log carries the certificates of the code that signs
the log - recursion named, marketing dropped)
- Author: Olaf Horvath, contact Olaf.Horvath@zkdefi.org, single URL
ltl.zkdefi.org (redundant zkdefi.org line removed)
- PDF rebuilt (4 pages), page 1 visually inspected
- title echoes updated: llms.txt, LTL docs-page paper card
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- web.py: /paper (and /paper/ltl.pdf) serve the committed PDF, loaded
once at startup from the repo checkout; listed in the 404 endpoint
index; covered by the web roundtrip test
- docs page: 'The paper' card linking the PDF
- DEPLOY.md: the second witness mirror belongs on a host the operator
does NOT control (a self-hosted mirror adds no equivocation defense)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- serve/webdocs/cli default to base_path='' (own subdomain, root serving)
- webdocs link builder handles the empty base like web.py already did
- all docs, paper, notebook 06b, and published-mirror README point at
https://ltl.zkdefi.org; DEPLOY.md rewritten for subdomain + redirect
- tests: root mount is the production shape; one test keeps exercising
the path-mounted variant
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The /docs route is now a real landing site (still one self-contained
HTML, inline CSS + inline SVG, zero external assets):
- One-sentence definition up top: what the LTL is and the cost
asymmetry it exists for (one signature + a few hashes in
milliseconds vs hours of theorem proving).
- THE GRAPHIC: the accumulator itself, rendered server-side from the
LIVE log at page load - real leaf hashes, real internal nodes, the
real root and signature. Green leaves are boundary-exact verified
attestations; grey leaves are the historical audit-failure entries,
labeled "kept forever - an append-only ledger does not erase its bad
day". The signature box names the dogfood backend and the provider's
self-inclusion check (the signature vouches for the code; the tree
vouches for the signature's code).
- "What do I download?" - exactly three artifacts, numbered, each with
what-it-is and where: (1) provider.ed25519.pub, the sole trust
anchor, cross-checkable between this site and the GitHub mirror;
(2) the attestation = the claim; (3) the receipt = the proof of
inclusion. Plus the maximal-benefit path: clone the mirror, run
verify.py --all, become a witness.
- Three usage lanes (quick check / zero-install audit / autonomous
agent), the API, and the means / does-NOT-mean cards.
Rendered against the real 8-leaf log and content-asserted in tests'
presence. 54/54 green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Socratic pass over everything this public repo reveals, adversary-first:
- DEPLOY.md no longer names the hosting provider or the server's other
software inventory (that sentence was NEW public information - the
site's front page does not advertise it). It now states its own
redaction policy up front, leads with a Caddy proxy config (matching
what the target site actually fronts with), adds rate-limiting and
proxy timeouts for the stdlib backend, generalizes the second-mirror
section, and gains an explicit key-hygiene section (the signing key
never touches the public server; a compromised box has nothing to
rotate).
- Future attestations stop leaking provider-machine paths: the
machine_protection guard path is recorded repo-relative and the Lean
project dir is recorded in its configured env-var form, never
machine-resolved. (The 12 already-published leaves containing local
home paths are immutable by design - severity assessed low: a local
username on a non-addressable dev box, no credentials - and an
append-only log does not rewrite its history.)
Audited clean: no keys, tokens, or credential-named files anywhere in
git history; no public IPs; loopback-only binds; commit identity is the
owner's long-standing public one. 54/54 tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
pacta's replay invoked `lake env lean` bare - on the reference machine
that is exactly the pattern that once OOM-crashed the host (see the
corpus' POSTMORTEM). New RepoConfig.lean_guard (set for all five repos
in examples/repos.yaml: verification/lean-guard): when configured,
every compile and axiom audit runs `lake env <guard> <file> --root=...`
instead of bare lean - hard memory cap via systemd scope + lean -M,
core pinning, timeout, single-flight lock, free-RAM preflight with the
Guard-3a retry ladder, all tuned via LEAN_MEM_MB / LEAN_MIN_FREE_MB /
LEAN_MEM_WAIT_SEC / LEAN_TIMEOUT / LEAN_MAX_CORES. Provider
attestations now record a machine_protection block naming the guard
(or "UNGUARDED"). Smoke-tested live on the real dalek repo: clamping
trace visible, compile green. 49/49 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
The verified corpus completed its phase 2 on 2026-07-06: every ed25519
fork now carries FOUR button-enforced apex tiers up to the full lift
(accept <=> decompress(R) = [k](-A)+[s]B as points), the complete scalar
layer, and the constructive encoding/decoding chain. pacta was calibrated
to the pre-apex corpus and - worse - had no vocabulary for
boundary-audited certificates: its axiom audit knew only "clean = exactly
the three standard axioms", so the apex tiers would have scored dirty.
New vocabulary:
- Profile.certificate_axioms: per-certificate ALLOWED axiom sets;
expected_axioms_for(cert) resolves each certificate's own boundary.
- RepoConfig.apex_boundary: a simple per-fork key (dalek-wrappers /
hash3 / anza) expanded by the ed25519 profile into the exact
per-tier allowed sets. AUTHORITY NOTE in profiles/ed25519.py: each
repo's check.sh Phase 3b is the enforcement point; if the button and
this table disagree, the button wins.
- run_axiom_audit compares each certificate against ITS allowed set;
deviation in EITHER direction (extra axiom or missing boundary
axiom) is dirty.
New risk reality:
- R4 is now reachable: full four-tier apex + constructive chain +
scalar arithmetic, all proven with cones pinned to their documented
boundaries. R4 always carries explicit residual blockers (SHA-512
oracle, hypothesis-parametric wire parses, translation faithfulness,
no side-channel/build assurance - those gate R5).
- R3 unchanged (arithmetic pair) and now explains exactly which apex
certificates are missing for R4.
Attestation trust model hardened:
- The provider is trusted for its OBSERVATION, never its VERDICT:
axiom_status is re-derived locally from observed_axioms against the
agent's own boundary policy. A provider that labels a dirty cone
"clean" gains nothing; "proven" with no observed axioms is
"unverifiable".
- Partial attestations degrade instead of being rejected: uncovered
certificates stay unproven and the score caps accordingly (an
arithmetic-only attestation still authorizes an R3 library capsule,
never a wallet).
Also: scripts/mini_pytest.py - a dependency-free test runner (tmp_path,
raises, monkeypatch, capsys) for hosts without pytest; examples
regenerated FROM the tool (dalek/anza fixtures now R4, 16 certs; new
full four-tier attestation example); tests updated + new
tests/test_boundaries.py (lying-provider, missing-boundary-axiom,
partial-coverage cases). 40/40 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>