← touchstone.cv

Touchstone · the toolkit

Every primitive, what it proves —
and what it can't.

Touchstone is a set of small, independent claims a stranger can re-derive, each with its residual named rather than hidden. This is the whole set: one card per primitive, with the dependency-free verifier that checks it and the endpoint it reads. Provenance, not quality — so every card is honest about the line it stops at.

pip install "touchstone-verify[record]" · verify and mint, one crypto core

Per record — is this entry sound?

Integrity unaltered

A disclosure re-derives from nothing but itself.

provesUnaltered, attributed, ordered — entry hashes recompute, the subject's Ed25519 signature holds across key rotation, checkpoints are append-only and witness-cosigned.
can'tCompleteness — that no entry was withheld. That's Standing + Completeness.

Time interval when

server_ts as a checkable [not-before, not-after].

provesA drand round folded in is the not-before (no back-dating); an OpenTimestamps→Bitcoin anchor is the not-after (no forward-swap). Each leg carries a typed tier naming which impl signed off.
can'tResolve finer than Bitcoin's ~2h block-time granularity — published, not papered over.
beacon-verify.py/…/entry/{seq}

Collusion floor k

How many must collude before a column is false.

provesPer column, k = min independent parties to falsify it — k=0 re-derivable, k≥2 witnessed (distinct control), k=1 testimony. Computed from evidence, never the declared grade.
can'tSee hidden shared control — sock-puppets under one operator collapse to one, so k is an upper bound.

Control depth how deep

How far control-disjointness re-derives.

provesA depth D along key → operator → boot → lineage — the deepest run that re-measures rather than asserts.
can'tAnything below D is testimony — the ladder stops where the evidence does.

Across records — the negatives you couldn't check before

Standing uncontested

Has anyone filed a Bitcoin-anchored objection?

provesNo contest is anchored against a digest before your freshness horizon — a contest rides the same anchored chain, so the channel can't silently drop it. "Uncontested" becomes checkable.
can'tProve the channel accepted every submission — a refused contestant publishes a self-authenticating SIGNED-BUT-ABSENT object.

Completeness both sides

Is a co-signed entry in the counterparty's own log?

provesBILATERAL (both anchored the same content) or CO-SIGNED-BUT-ABSENT (B acknowledged it, yet B's complete anchored log omits it as of block N).
can'tCall one-sided absence "suppression" — absence alone isn't; absence plus a counterparty's signature is.

Uniqueness one chain

Is this the recorder they publicly run — or a shadow?

provesThe recorder is BOUND to the single set of chains its operator signed a commitment to — a chain shown only to you reads UNREGISTERED.
can'tReach fork consistency from one bundle — uniqueness needs a second observer (gossip / witnesses), by construction.

Composed — many records, or many axes

Composition multi-agent

N agents, one decision, independence kept.

provesN per-agent receipts each fold to Bitcoin and are named exactly (no post-hoc swap), with floor k = distinct control across the contributing chains. Linked, not merged — a shared chain would read k=1.
can'tSee hidden shared control (k upper bound), or prove the agents actually cooperated.
compose-verify.py/composition/{rec}/{seq}

Trust profile no scalar

Every axis at once, fail-closed, no combined score.

provesGrades independent axes — control depth, collusion floor, time interval — each an upper bound, each fail-closed, by loading the sibling verifiers (one crypto core).
can'tGive a single number — deliberately. Gate on the axis your decision needs and tighten its floor with what you know.

Mint producer

Sign a receipt locally in three lines.

provesThe same package that verifies also mints — one crypto core, so what you sign is byte-for-byte what a stranger re-derives; your key never leaves the process.
can'tMake you trust the server — canonicalization is local, so a hostile server can't slip you a different commitment.

Independence & honesty — the deepest-ancestor layer

Independence honest quorum

Five sources over one feed are k=1, not k=5.

provesA quorum commits each input's derivation roots; the floor is the min roots to corrupt to falsify the whole quorum. Exposes a signer count "dressed" as more independent than it is.
can'tSee an undeclared shared root (upper bound, claimant-owned).
independence-verify.py/quorum/{rec}/{seq}

Lineage recorded derivation

Commit what you derived from; walk it.

provesWalks derived_from transitively (diamonds collapse) to the committed roots — the distinct-root k over real lineage, and the quarantine selector: is this output downstream of a losing head / corrupted source?
can'tRecover lineage a producer never recorded — you can only walk what was committed.
lineage-verify.py/derivation/{rec}/{seq}

Scope signed omissions

A verifier that signs what it did NOT check.

provesA signed manifest enumerates every canonical check as pass / fail / skipped, so "valid" can't imply completeness. Omission is unforgeable — the signature covers the whole list, and a missing check reads INCOMPLETE, not a silent pass.
can'tMake a skipped check true — it only makes the gap honest and un-hideable.

Composite strength k × tier

Independence count and trust tier as ONE point — neither inflatable by the other.

provesA quorum's honest strength is a point (k, tier) on a partial-order lattice: k = distinct derivation roots (a floor, never a union), tier = the meet across those roots. Stacking cheap witnesses lifts k but drags the tier-meet down; claiming a high tier on one root leaves k=1. Both levers refused at once — fed live from lineage-verify's walked roots.
can'tRaise itself by hidden shared control (k is an upper bound), or by an axis the relier won't accept — which is why the tier is a named tier, not a scalar.

Decorrelation probe measured, not declared

Independence you measure by shared failure — not by counting agreements.

provesWitnesses that fail differently are independent; a shared corpus or method lands them on the same wrong answer. Reads the pairwise same-wrong rate on a beacon-drawn, single-use, unmemorizable probe set — an exam nobody controlled, drawn after the witnesses commit.
can'tCertify independence in general — only fail to reject it on this exam. The verdict is a null-rejection enum, never a bare "independent"; a too-small both-wrong cell or high abstention fails closed.
decorrelation-leg2.py--gen · --verify · --score

Two things that hold across all of it

Independence bottoms out at the deepest shared ancestor.

Two witnesses under one key are k=1, not k=2. Two confirmations reading the same scoreboard are one reader with two badges. Independence isn't about distinct principals — it's the number of disjoint derivation paths from source. Every floor in the toolkit is that count.

The publisher states the observable; the relier prices the risk.

The record carries bare facts — an age, an interval width, a tier, a floor. The tunable knob — freshness horizon, sweep tolerance, which tier you accept, how much decay — lives relier-side. Anything a publisher sets about its own trustworthiness is a claim about itself; the part that binds is the reader's.